-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
unnest JSON.Rule.Root to JSON.Rule and add LintingDictionary snippet (#…
…42)
- Loading branch information
1 parent
a7e049b
commit 59d34c5
Showing
4 changed files
with
147 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import JSON | ||
|
||
// ``JSON//LintingDictionary`` provides a lightweight functional interface | ||
// for decoding JSON messages with built-in error handling. | ||
|
||
// snippet.market-enum-definition | ||
enum Market:String | ||
{ | ||
case spot | ||
case future | ||
} | ||
// snippet.main | ||
func decode(message:String) throws -> | ||
( | ||
name:String, | ||
market:Market, | ||
isPerpetual:Bool | ||
) | ||
{ | ||
// snippet.parse | ||
let json:JSON = try Grammar.parse(message.utf8, | ||
as: JSON.Rule<String.Index>.self) | ||
// snippet.decode | ||
return try json.lint | ||
{ | ||
try $0.remove("market") | ||
{ | ||
try $0.lint | ||
{ | ||
// snippet.decode-string | ||
let name:String = try $0.remove("name", as: String.self) | ||
|
||
|
||
// snippet.decode-enum | ||
let market:Market = try $0.remove("type") | ||
{ | ||
try $0.as(cases: Market.self) | ||
} | ||
|
||
// snippet.decode-conditional | ||
let isPerpetual:Bool | ||
if case .future = market | ||
{ | ||
isPerpetual = try $0.pop("perpetual", as: Bool.self) ?? false | ||
} | ||
else | ||
{ | ||
isPerpetual = false | ||
} | ||
// snippet.return | ||
return (name, market, isPerpetual) | ||
} | ||
} | ||
} | ||
} | ||
// snippet.example-success | ||
print(try decode(message: | ||
""" | ||
{ | ||
"market": | ||
{ | ||
"name": "BTC-PERP", | ||
"type": "future", | ||
"perpetual": true | ||
} | ||
} | ||
""")) | ||
|
||
// snippet.example-failure | ||
print(try decode(message: | ||
""" | ||
{ | ||
"market": | ||
{ | ||
"name": "BTC-PERP", | ||
"type": "spot", | ||
"perpetual": true | ||
} | ||
} | ||
""")) | ||
|
||
// snippet.hide | ||
extension JSON.LintingDictionary | ||
{ | ||
private mutating | ||
func lintArrays(_ key:String, as _:[JSON].Type, _ body:([JSON]) throws -> ()) throws | ||
{ | ||
// snippet.pop-array-equivalence | ||
try self.pop(key) | ||
{ | ||
try body(try $0.as([JSON].self)) | ||
} | ||
// snippet.hide | ||
// snippet.pop-array-or-null-equivalence | ||
try self.pop(key) | ||
{ | ||
try $0.as([JSON]?.self).map(body) | ||
} ?? nil | ||
// snippet.hide | ||
// snippet.remove-array-equivalence | ||
try self.remove(key) | ||
{ | ||
try body(try $0.as([JSON].self)) | ||
} | ||
// snippet.hide | ||
// snippet.remove-array-or-nullequivalence | ||
try self.remove(key) | ||
{ | ||
try $0.as([JSON]?.self).map(body) | ||
} | ||
// snippet.hide | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters