GithubHelp home page GithubHelp logo

nunoalexandre / stork Goto Github PK

View Code? Open in Web Editor NEW
4.0 1.0 0.0 103 KB

Delivering types from JSON like a Stork

License: BSD 3-Clause "New" or "Revised" License

Objective-C 2.52% Swift 94.00% Ruby 3.48%
swift json-parser functional-programming json protocol swift5

stork's Introduction

Stork

Stork is a lightweight library focused on making the flight from JSON to Types as smooth as possible. Stork believes in simplicity, explicitness, and control.

Based on functional programming principles and mildly inspired in Aeson, Stork is the middle sweet between JSON parsers such as Argo - full-fledged but requiring extra dependencies and too functional for some - and other parsers that require your types to be mutable, to throw on init, or that take the control away from you.

How it works

To go from JSON to types, all you need to do is to state what fields you want to parse. Stork infers their type and parses them for you. To make that possible, your types must follow the FromJson protocol.

protocol FromJson {
  static func from(value: JsonValue) -> Self?
}

In practice, this means that for a type to be parseable from JSON, it needs to provide a way of being constructed from a JsonValue: string, number, bool, JSON, or [JsonValue].

At compile-time, Storks requires the types you want to get from JSON to be FromJson compliant. Otherwise, you encounter the following compile error message on Xcode:

Generic parameter 'T' could not be infered

Examples

Say that we want to retrieve values of type User from some JSON input, where User and its nested types are defined as follows:

struct User {
  let id: Int
  let name: String
  let email: String?
  let country: Country?
  let subscription: Subscription
  let favouriteSongs: [Song]
}

enum Subscription: String {
  case free
  case bronze
  case silver
  case gold
}

enum Country: String {
  case netherlands
  case portugal
}

struct Song: Equatable {
  let name: String
  let band: String
}

With Stork, to go from JSON to this model all we need to do is to have these types complying to our FromJson protocol.

extension User: FromJson {
  static func from(value: JsonValue) -> User? {
    return value.ifObject { json in
      User(
        id:             try json .! "id",
        name:           try json .! "name",
        email:          json .? "email",
        country:        json .? "country",
        subscription:   try json .! "subscription",
        favouriteSongs: (json ..? "favouriteSongs") ?? []
      )
    }
  }
}

// That's all you need for String/Int RawRepresentable Enums!
extension Subscription: FromJson {}

// Or you get to say how it's done!
// In this case, the country in JSON is short-coded and
// thus needs to be translated to the right Country case.
extension Country: FromJson {
  static func from(value: JsonValue) -> Country? {
    return value.ifString { str in
      switch str {
      case "nl": return .netherlands
      case "pt": return .portugal
      default:   return nil
      }
    }
  }
}

extension Song: FromJson {
  static func from(value: JsonValue) -> Song? {
    return value.ifObject { json in
      Song(
        name: try json .! "name",
        band: try json .! "band"
      )
    }
  }
}

Now that we have everything, let's get Stork to deliver that baby:

// Single user
let maybeUser: User? = User.from(json: userJSON)

// Array of users
let users: [User] = [User].from(jsonArray: usersJSON)

See more, unit-tested examples at the Examples directory

Installation

You can add Stork as a dependency to your project via the following ways.

  1. To add Stork to your Xcode project using CocoaPods, add this line to your Podfile:
pod 'StorkEgg', '0.2.1'

Note: The pod name is StorkEgg since Stork was already taken.

  1. Then let CocoaPods fetch and install it for you:
pod install
  1. Finally, build your project and import Stork:
import Stork

Git Submodules

# Add Stork as a git submodule to your repository
git submodule add [email protected]:NunoAlexandre/stork.git
# Get the most updated version of Stork
git submodule update --remote

Read more about Git Submodules here.

TODO

I plan to support Carthage and the Swift Package Manager.

Help is rather appreciated!

stork's People

Contributors

nunoalexandre avatar honga1 avatar

Stargazers

Justin Madewell avatar  avatar Sacha DSO avatar Robert Kreuzer avatar

Watchers

James Cloos avatar

stork's Issues

Consider adding a 'DecodeResult' value instead of using optionals

Now we are blind in optionals. That means that we don't know why a computation failed.
There are two critical drawbacks now, where whenever 1) an expected required field is missing or its expected type is wrong, no information is passed on to provide a clear suggestion of what is wrong and must be fixed.

Add more examples

  • Show how to get a list of Ts from a given [JSON]
  • Show how to handle backwards-compatibility
  • Show how to build a type from different JsonValues.

Write a complete and friendly README

The structure of the page should be something like this:

  • 1. Name + Logo(todo)
    • 1.1 Description
  • 2. Table of contents
  • 3. How it works (It'd be nice to have an illustration explaining the dots and the flow)
  • 4. Examples
  • 5. Installation (#6)
    • cocoa
    • carthage
    • swift package manager

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.