Skip to content

Commit

Permalink
Rename JSON to Value
Browse files Browse the repository at this point in the history
We're going to be shifting the marketing focus for Argo away from being a JSON
parser and towards being a general purpose parser for transforming loosely
typed data models into strongly typed ones. As a part of this change, we can
generalize our types a bit, and use the name `Value` for our input values,
instead of `JSON`. This change is purely cosmetic, but will result in a more
general API, letting us break a bit from our ties to JSON.
  • Loading branch information
gfontenot committed Apr 29, 2018
1 parent 40f2e2e commit 66be851
Show file tree
Hide file tree
Showing 22 changed files with 334 additions and 334 deletions.
20 changes: 10 additions & 10 deletions Argo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
4D5F6DDA1B3832C200D79B25 /* user_with_nested_name.json in Resources */ = {isa = PBXBuildFile; fileRef = 4D5F6DD81B3832C200D79B25 /* user_with_nested_name.json */; };
809754CB1BADF34200C409E6 /* Argo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 809754C11BADF34100C409E6 /* Argo.framework */; };
809754D81BADF36D00C409E6 /* Decoded.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB69E1ABC5F1300E3B0AB /* Decoded.swift */; };
809754D91BADF36D00C409E6 /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB69F1ABC5F1300E3B0AB /* JSON.swift */; };
809754D91BADF36D00C409E6 /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB69F1ABC5F1300E3B0AB /* Value.swift */; };
809754DA1BADF36D00C409E6 /* Decodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB6A01ABC5F1300E3B0AB /* Decodable.swift */; };
809754DB1BADF36D00C409E6 /* StandardTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB6A11ABC5F1300E3B0AB /* StandardTypes.swift */; };
809754DC1BADF36D00C409E6 /* DecodeError.swift in Sources */ = {isa = PBXBuildFile; fileRef = F84318A71B9A2D7A00165216 /* DecodeError.swift */; };
Expand Down Expand Up @@ -59,7 +59,7 @@
8097550A1BADF3F200C409E6 /* types.plist in Resources */ = {isa = PBXBuildFile; fileRef = EABDF68E1A9CD4EA00B6CC83 /* types.plist */; };
BF92789D1B9365900038A7E1 /* RawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF92789C1B9365900038A7E1 /* RawRepresentable.swift */; };
D0592EBE1B77DD8E00EFEF39 /* Decoded.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB69E1ABC5F1300E3B0AB /* Decoded.swift */; };
D0592EBF1B77DD8E00EFEF39 /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB69F1ABC5F1300E3B0AB /* JSON.swift */; };
D0592EBF1B77DD8E00EFEF39 /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB69F1ABC5F1300E3B0AB /* Value.swift */; };
D0592EC01B77DD8E00EFEF39 /* Decodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB6A01ABC5F1300E3B0AB /* Decodable.swift */; };
D0592EC11B77DD8E00EFEF39 /* StandardTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB6A11ABC5F1300E3B0AB /* StandardTypes.swift */; };
D0592EC51B77DD9A00EFEF39 /* decode.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB69A1ABC5F1300E3B0AB /* decode.swift */; };
Expand Down Expand Up @@ -169,8 +169,8 @@
F87EB6A91ABC5F1300E3B0AB /* sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB69C1ABC5F1300E3B0AB /* sequence.swift */; };
F87EB6AA1ABC5F1300E3B0AB /* Decoded.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB69E1ABC5F1300E3B0AB /* Decoded.swift */; };
F87EB6AB1ABC5F1300E3B0AB /* Decoded.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB69E1ABC5F1300E3B0AB /* Decoded.swift */; };
F87EB6AC1ABC5F1300E3B0AB /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB69F1ABC5F1300E3B0AB /* JSON.swift */; };
F87EB6AD1ABC5F1300E3B0AB /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB69F1ABC5F1300E3B0AB /* JSON.swift */; };
F87EB6AC1ABC5F1300E3B0AB /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB69F1ABC5F1300E3B0AB /* Value.swift */; };
F87EB6AD1ABC5F1300E3B0AB /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB69F1ABC5F1300E3B0AB /* Value.swift */; };
F87EB6AE1ABC5F1300E3B0AB /* Decodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB6A01ABC5F1300E3B0AB /* Decodable.swift */; };
F87EB6AF1ABC5F1300E3B0AB /* Decodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB6A01ABC5F1300E3B0AB /* Decodable.swift */; };
F87EB6B01ABC5F1300E3B0AB /* StandardTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87EB6A11ABC5F1300E3B0AB /* StandardTypes.swift */; };
Expand Down Expand Up @@ -333,7 +333,7 @@
F87EB69B1ABC5F1300E3B0AB /* flatReduce.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = flatReduce.swift; sourceTree = "<group>"; };
F87EB69C1ABC5F1300E3B0AB /* sequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = sequence.swift; sourceTree = "<group>"; };
F87EB69E1ABC5F1300E3B0AB /* Decoded.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Decoded.swift; sourceTree = "<group>"; };
F87EB69F1ABC5F1300E3B0AB /* JSON.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSON.swift; sourceTree = "<group>"; };
F87EB69F1ABC5F1300E3B0AB /* Value.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Value.swift; sourceTree = "<group>"; };
F87EB6A01ABC5F1300E3B0AB /* Decodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Decodable.swift; sourceTree = "<group>"; };
F87EB6A11ABC5F1300E3B0AB /* StandardTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StandardTypes.swift; sourceTree = "<group>"; };
F89335541A4CE83000B88685 /* Argo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Argo.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -569,7 +569,7 @@
isa = PBXGroup;
children = (
EA04D5A81BBF43C7001DE23B /* Decoded */,
F87EB69F1ABC5F1300E3B0AB /* JSON.swift */,
F87EB69F1ABC5F1300E3B0AB /* Value.swift */,
F87EB6A01ABC5F1300E3B0AB /* Decodable.swift */,
F87EB6A11ABC5F1300E3B0AB /* StandardTypes.swift */,
F84318A71B9A2D7A00165216 /* DecodeError.swift */,
Expand Down Expand Up @@ -979,7 +979,7 @@
EA9159FA1BDE74F300D85292 /* Applicative.swift in Sources */,
809754E51BADF36D00C409E6 /* Dictionary.swift in Sources */,
809754E61BADF36D00C409E6 /* RawRepresentable.swift in Sources */,
809754D91BADF36D00C409E6 /* JSON.swift in Sources */,
809754D91BADF36D00C409E6 /* Value.swift in Sources */,
F8C2561C1C3C855C00B70968 /* NSNumber.swift in Sources */,
EA9159FB1BDE74F800D85292 /* Alternative.swift in Sources */,
);
Expand Down Expand Up @@ -1025,7 +1025,7 @@
EA04D5A31BBF2021001DE23B /* FailureCoalescing.swift in Sources */,
D0592EBE1B77DD8E00EFEF39 /* Decoded.swift in Sources */,
F84318AA1B9A2D7A00165216 /* DecodeError.swift in Sources */,
D0592EBF1B77DD8E00EFEF39 /* JSON.swift in Sources */,
D0592EBF1B77DD8E00EFEF39 /* Value.swift in Sources */,
F8EF43311BBC729F001886BA /* catDecoded.swift in Sources */,
EA1200CE1BAB621C006DDBD8 /* RawRepresentable.swift in Sources */,
EA04D5931BBF1F40001DE23B /* Monad.swift in Sources */,
Expand All @@ -1046,7 +1046,7 @@
F87EB6AE1ABC5F1300E3B0AB /* Decodable.swift in Sources */,
F87EB6A41ABC5F1300E3B0AB /* decode.swift in Sources */,
F82D15F31C3C82730079FFB5 /* NSNumber.swift in Sources */,
F87EB6AC1ABC5F1300E3B0AB /* JSON.swift in Sources */,
F87EB6AC1ABC5F1300E3B0AB /* Value.swift in Sources */,
EA04D5A11BBF2021001DE23B /* FailureCoalescing.swift in Sources */,
F87EB6A61ABC5F1300E3B0AB /* flatReduce.swift in Sources */,
F87EB6A81ABC5F1300E3B0AB /* sequence.swift in Sources */,
Expand Down Expand Up @@ -1094,7 +1094,7 @@
F87EB6AF1ABC5F1300E3B0AB /* Decodable.swift in Sources */,
EA04D59E1BBF1FB9001DE23B /* Alternative.swift in Sources */,
F87EB6A51ABC5F1300E3B0AB /* decode.swift in Sources */,
F87EB6AD1ABC5F1300E3B0AB /* JSON.swift in Sources */,
F87EB6AD1ABC5F1300E3B0AB /* Value.swift in Sources */,
F8C2561A1C3C855B00B70968 /* NSNumber.swift in Sources */,
F87EB6A71ABC5F1300E3B0AB /* flatReduce.swift in Sources */,
EA04D5A21BBF2021001DE23B /* FailureCoalescing.swift in Sources */,
Expand Down
34 changes: 17 additions & 17 deletions Documentation/Curry-Limitations.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ struct User: Decodable {
let mediumAvatar: String
let largeAvatar: String

static func decode(j: JSON) -> Decoded<User> {
static func decode(v: Value) -> Decoded<User> {
return curry(User.init)
<^> j <| "id"
<*> j <| "name"
<*> j <| "bio"
<*> j <| "small_avatar"
<*> j <| "medium_avatar"
<*> j <| "large_avatar"
<^> v <| "id"
<*> v <| "name"
<*> v <| "bio"
<*> v <| "small_avatar"
<*> v <| "medium_avatar"
<*> v <| "large_avatar"
}
}
```
Expand All @@ -59,29 +59,29 @@ struct Avatar {

Now `User.init` has 4 arguments and `Avatar.init` has 3 arguments, so we are
within the assumed limitations of `curry`. But, it is also less clear how we
should write `User.decode`. How can we extract the 3 avatar fields from `JSON`
should write `User.decode`. How can we extract the 3 avatar fields from `Value`
to build `Avatar` first, and then use that to build `User`? The key insight is
to see that `j <| "key"` returns a `Decoded<T>` value, representing one step
of decoding. So, we can decode a `Avatar` first using `j`, and then plug that
directly into `curry(User.init)`:

```swift
extension Avatar: Decodable {
static func decode(j: JSON) -> Decoded<Avatar> {
static func decode(v: Value) -> Decoded<Avatar> {
return curry(Avatar.init)
<^> j <| "small_avatar"
<*> j <| "medium_avatar"
<*> j <| "large_avatar"
<^> v <| "small_avatar"
<*> v <| "medium_avatar"
<*> v <| "large_avatar"
}
}

extension User: Decodable {
static func decode(j: JSON) -> Decoded<User> {
static func decode(v: Value) -> Decoded<User> {
return curry(User.init)
<^> j <| "id"
<*> j <| "name"
<*> j <| "bio"
<*> Avatar.decode(j)
<^> v <| "id"
<*> v <| "name"
<*> v <| "bio"
<*> Avatar.decode(v)
}
}
```
Expand Down
2 changes: 1 addition & 1 deletion Documentation/Decode-Enums.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ We can write `Decodable` for `FootRace` like so:

```swift
extension FootRace: Decodable {
static func decode(j: JSON) -> Decoded<FootRace> {
static func decode(j: Value) -> Decoded<FootRace> {
switch j {

// First, make sure JSON is a number.
Expand Down
16 changes: 8 additions & 8 deletions Sources/Argo/Extensions/RawRepresentable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
`String` as the raw value.
*/
public extension Decodable where Self.DecodedType == Self, Self: RawRepresentable, Self.RawValue == String {
static func decode(_ json: JSON) -> Decoded<Self> {
switch json {
static func decode(_ value: Value) -> Decoded<Self> {
switch value {
case let .string(s):
return self.init(rawValue: s)
.map(pure) ?? .typeMismatch(expected: "rawValue for \(self)", actual: json)
.map(pure) ?? .typeMismatch(expected: "rawValue for \(self)", actual: value)
default:
return .typeMismatch(expected: "String", actual: json)
return .typeMismatch(expected: "String", actual: value)
}
}
}
Expand All @@ -19,13 +19,13 @@ public extension Decodable where Self.DecodedType == Self, Self: RawRepresentabl
`Int` as the raw value.
*/
public extension Decodable where Self.DecodedType == Self, Self: RawRepresentable, Self.RawValue == Int {
static func decode(_ json: JSON) -> Decoded<Self> {
switch json {
static func decode(_ value: Value) -> Decoded<Self> {
switch value {
case let .number(n):
return self.init(rawValue: n.intValue)
.map(pure) ?? .typeMismatch(expected: "rawValue for \(self)", actual: json)
.map(pure) ?? .typeMismatch(expected: "rawValue for \(self)", actual: value)
default:
return .typeMismatch(expected: "Int", actual: json)
return .typeMismatch(expected: "Int", actual: value)
}
}
}
8 changes: 4 additions & 4 deletions Sources/Argo/Functions/decode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
- returns: A `Decoded<T>` value where `T` is `Decodable`
*/
public func decode<T: Decodable>(_ object: Any) -> Decoded<T> where T == T.DecodedType {
return T.decode(JSON(object))
return T.decode(Value(object))
}

/**
Expand Down Expand Up @@ -56,7 +56,7 @@ public func decode<T: Decodable>(_ object: Any) -> T? where T == T.DecodedType {
Attempt to transform `Any` into a `Decodable` value using a specified
root key.

This function attempts to extract the embedded `JSON` object from the
This function attempts to extract the embedded `Value` object from the
dictionary at the specified key and transform it into a `Decodable` value.
This works based on the type you ask for.

Expand All @@ -79,14 +79,14 @@ public func decode<T: Decodable>(_ object: Any) -> T? where T == T.DecodedType {
- returns: A `Decoded<T>` value where `T` is `Decodable`
*/
public func decode<T: Decodable>(_ dict: [String: Any], rootKey: String) -> Decoded<T> where T == T.DecodedType {
return JSON(dict as Any)[rootKey]
return Value(dict as Any)[rootKey]
}

/**
Attempt to transform `Any` into a `Decodable` value using a specified
root key and return an `Optional`.

This function attempts to extract the embedded `JSON` object from the
This function attempts to extract the embedded `Value` object from the
dictionary at the specified key and transform it into a `Decodable` value,
returning an `Optional`. This works based on the type you ask for.

Expand Down
8 changes: 4 additions & 4 deletions Sources/Argo/Types/Decodable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ public protocol Decodable {
associatedtype DecodedType = Self

/**
Decode an object from JSON.
Decode an object from Value.

This is the main entry point for Argo. This function declares how the
conforming type should be decoded from JSON. Since this is a failable
conforming type should be decoded from Value. Since this is a failable
operation, we need to return a `Decoded` type from this function.

- parameter json: The `JSON` representation of this object
- parameter value: The `Value` representation of this object

- returns: A decoded instance of the `DecodedType`
*/
static func decode(_ json: JSON) -> Decoded<DecodedType>
static func decode(_ value: Value) -> Decoded<DecodedType>
}
4 changes: 2 additions & 2 deletions Sources/Argo/Types/DecodeError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ public enum DecodeError: Error {
/// The type existing at the key didn't match the type being requested.
case typeMismatch(expected: String, actual: String)

/// The key did not exist in the JSON.
/// The key did not exist in the Value.
case missingKey(String)

/// A custom error case for adding explicit failure info.
case custom(String)

/// There were multiple errors in the JSON.
/// There were multiple errors in the Value.
case multiple([DecodeError])
}

Expand Down
Loading

0 comments on commit 66be851

Please sign in to comment.