Skip to content

Commit c1ec24d

Browse files
committed
simplify JSONValue
1 parent 2fbdd81 commit c1ec24d

File tree

5 files changed

+81
-252
lines changed

5 files changed

+81
-252
lines changed

FlyingFox/Sources/JSON/JSONValuePattern.swift renamed to FlyingFox/Sources/JSON/JSONBodyPattern.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@
3131

3232
import Foundation
3333

34-
public extension HTTPBodyPattern where Self == JSONValuePattern {
34+
public extension HTTPBodyPattern where Self == JSONBodyPattern {
3535

36-
static func jsonValue(where predicate: @escaping @Sendable (JSONValue) throws -> Bool) -> JSONValuePattern {
37-
JSONValuePattern(predicate)
36+
static func jsonValue(where predicate: @escaping @Sendable (JSONValue) throws -> Bool) -> JSONBodyPattern {
37+
JSONBodyPattern(predicate)
3838
}
3939
}
4040

41-
public struct JSONValuePattern: HTTPBodyPattern {
41+
public struct JSONBodyPattern: HTTPBodyPattern {
4242

4343
private let predicate: @Sendable (JSONValue) throws -> Bool
4444

FlyingFox/Sources/JSON/JSONValue.swift

Lines changed: 33 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -130,52 +130,22 @@ public extension JSONValue {
130130
} else {
131131
self = .number(nsNumber.doubleValue)
132132
}
133-
} else if let int = any as? Int {
134-
self = .number(Double(int))
135-
} else if let double = any as? Double {
136-
self = .number(double)
137-
} else if let bool = any as? Bool {
138-
self = .boolean(bool)
139133
} else if any is NSNull {
140134
self = .null
135+
} else if case nil as Any? = any {
136+
self = .null
141137
} else {
142138
throw Error("Unsupported Value")
143139
}
144140
}
145141

146-
init?(_ value: JSONValue?) {
147-
guard let value else { return nil }
148-
self = value
149-
}
150-
151-
init?(_ value: [String: JSONValue]?) {
152-
guard let value else { return nil }
153-
self = .object(value)
154-
}
155-
156-
init?(_ value: [JSONValue]?) {
157-
guard let value else { return nil }
158-
self = .array(value)
159-
}
160-
161-
init?(_ value: String?) {
162-
guard let value else { return nil }
163-
self = .string(value)
164-
}
165-
166-
init?(_ value: Double?) {
167-
guard let value else { return nil }
168-
self = .number(value)
169-
}
170-
171-
init?(_ value: Int?) {
172-
guard let value else { return nil }
173-
self = .number(Double(value))
174-
}
175-
176-
init?(_ value: Bool?) {
177-
guard let value else { return nil }
178-
self = .boolean(value)
142+
init<T>(_ any: T?) throws {
143+
switch any {
144+
case .none:
145+
self = .null
146+
case .some(let value):
147+
self = try JSONValue(value)
148+
}
179149
}
180150

181151
func asAny() -> Any {
@@ -195,54 +165,20 @@ public extension JSONValue {
195165
}
196166
}
197167

198-
func asObject() throws -> [String: JSONValue] {
168+
private func asObject() throws -> [String: JSONValue] {
199169
guard case let .object(val) = self else {
200170
throw Error("Expected object")
201171
}
202172
return val
203173
}
204174

205-
func asArray() throws -> [JSONValue] {
175+
private func asArray() throws -> [JSONValue] {
206176
guard case let .array(val) = self else {
207177
throw Error("Expected array")
208178
}
209179
return val
210180
}
211181

212-
func asString() throws -> String {
213-
guard case let .string(val) = self else {
214-
throw Error("Expected string")
215-
}
216-
return val
217-
}
218-
219-
func asNumber() throws -> Double {
220-
guard case .number(let val) = self else {
221-
throw Error("Expected number")
222-
}
223-
return val
224-
}
225-
226-
func asBool() throws -> Bool {
227-
switch self {
228-
case .boolean(let val):
229-
return val
230-
case .number(let val) where val == 0:
231-
return false
232-
case .number(let val) where val == 1:
233-
return true
234-
default:
235-
throw Error("Expected boolean")
236-
}
237-
}
238-
239-
func asNull() throws -> NSNull {
240-
guard case .null = self else {
241-
throw Error("Expected null")
242-
}
243-
return NSNull()
244-
}
245-
246182
private struct Error: LocalizedError {
247183
var errorDescription: String?
248184

@@ -261,96 +197,34 @@ public extension JSONValue {
261197
}
262198
}
263199

264-
public extension JSONValue {
265-
266-
mutating func updateValue(parsing text: String) throws {
267-
if let null = try? Self.parseNull(string: text) {
268-
self = null
269-
return
270-
}
271-
switch self {
272-
case .object:
273-
self = try Self.parseObject(string: text)
274-
case .array:
275-
self = try Self.parseArray(string: text)
276-
case .string:
277-
self = .string(text)
278-
case .number:
279-
self = try Self.parseNumber(string: text)
280-
case .boolean:
281-
self = try Self.parseBoolean(string: text)
282-
case .null:
283-
self = Self.parseAny(string: text)
284-
}
285-
}
200+
public func == (lhs: JSONValue, rhs: String) -> Bool {
201+
lhs == JSONValue.string(rhs)
202+
}
286203

287-
static func parseObject(string: String) throws -> JSONValue {
288-
let data = string.data(using: .utf8)!
289-
guard case let .object(object) = try JSONValue(data: data) else {
290-
throw Error("Invalid object")
291-
}
292-
return .object(object)
293-
}
204+
public func != (lhs: JSONValue, rhs: String) -> Bool {
205+
!(lhs == rhs)
206+
}
294207

295-
static func parseArray(string: String) throws -> JSONValue {
296-
let data = string.data(using: .utf8)!
297-
guard case let .array(array) = try JSONValue(data: data) else {
298-
throw Error("Invalid array")
299-
}
300-
return .array(array)
301-
}
208+
public func == (lhs: JSONValue, rhs: Double) -> Bool {
209+
lhs == JSONValue.number(rhs)
210+
}
302211

303-
static func parseNumber(string: String) throws -> JSONValue {
304-
guard let value = JSONValue.numberFormatter.number(from: string)?.doubleValue else {
305-
throw Error("Invalid number")
306-
}
307-
return .number(value)
308-
}
212+
public func != (lhs: JSONValue, rhs: Double) -> Bool {
213+
!(lhs == rhs)
214+
}
309215

310-
static func parseBoolean(string: String) throws -> JSONValue {
311-
switch string.lowercased() {
312-
case "true":
313-
return .boolean(true)
314-
case "false":
315-
return .boolean(false)
316-
default:
317-
throw Error("Invalid boolean")
318-
}
319-
}
216+
public func == (lhs: JSONValue, rhs: Bool) -> Bool {
217+
lhs == JSONValue.boolean(rhs)
218+
}
320219

321-
static func parseNull(string: String) throws -> JSONValue {
322-
switch string.lowercased() {
323-
case "null", "":
324-
return .null
325-
default:
326-
throw Error("Invalid null")
327-
}
328-
}
220+
public func != (lhs: JSONValue, rhs: Bool) -> Bool {
221+
!(lhs == rhs)
222+
}
329223

330-
static func parseAny(string: String) -> JSONValue {
331-
if let object = try? parseObject(string: string) {
332-
return object
333-
} else if let array = try? parseArray(string: string) {
334-
return array
335-
} else if let number = try? parseNumber(string: string) {
336-
return number
337-
} else if let bool = try? parseBoolean(string: string) {
338-
return bool
339-
} else if let null = try? parseNull(string: string) {
340-
return null
341-
} else {
342-
return .string(string)
343-
}
344-
}
224+
public func == (lhs: JSONValue, rhs: some BinaryInteger) -> Bool {
225+
lhs == JSONValue.number(Double(rhs))
345226
}
346227

347-
public extension JSONValue {
348-
static let numberFormatter: NumberFormatter = {
349-
let formatter = NumberFormatter()
350-
formatter.locale = Locale(identifier: "en_US")
351-
formatter.minimumFractionDigits = 0
352-
formatter.maximumFractionDigits = 6
353-
formatter.roundingMode = .halfUp
354-
return formatter
355-
}()
228+
public func != (lhs: JSONValue, rhs: some BinaryInteger) -> Bool {
229+
!(lhs == rhs)
356230
}

FlyingFox/Tests/JSON/JSONValuePatternTests.swift renamed to FlyingFox/Tests/JSON/JSONBodyPatternTests.swift

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// JSONValuePatternTests.swift
2+
// JSONBodyPatternTests.swift
33
// FlyingFox
44
//
55
// Created by Simon Whitty on 15/08/2024.
@@ -33,12 +33,12 @@ import FlyingFox
3333
import Foundation
3434
import Testing
3535

36-
struct JSONValuePatternTests {
36+
struct JSONBodyPatternTests {
3737

3838
@Test
3939
func pattern_MatchesJSONPath() async throws {
4040
// given
41-
let pattern = JSONValuePattern { try $0.getValue(for: "$.name") == .string("fish") }
41+
let pattern = JSONBodyPattern { try $0.getValue(for: "$.name") == "fish" }
4242

4343
// when then
4444
#expect(pattern.evaluate(json: #"{"name": "fish"}"#))
@@ -53,7 +53,7 @@ struct JSONValuePatternTests {
5353
// given
5454
let route = HTTPRoute(
5555
"POST /fish",
56-
jsonBody: { try $0.getValue(for: "$.food") == .string("chips") }
56+
jsonBody: { try $0.getValue(for: "$.food") == "chips" }
5757
)
5858

5959
// when
@@ -70,14 +70,13 @@ struct JSONValuePatternTests {
7070
}
7171
}
7272

73-
private extension JSONValuePattern {
73+
private extension JSONBodyPattern {
7474

7575
func evaluate(json: String) -> Bool {
7676
self.evaluate(Data(json.utf8))
7777
}
7878
}
7979

80-
8180
private extension HTTPRequest {
8281
static func make(method: HTTPMethod = .POST,
8382
version: HTTPVersion = .http11,

FlyingFox/Tests/JSON/JSONPathTests.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,16 @@ struct JSONPathTests {
8585
"""#)
8686

8787
#expect(
88-
try json.getValue(for: "$.owner.age").asNumber() == 7
88+
try json.getValue(for: "$.owner.age") == 7
8989
)
9090
#expect(
91-
try json.getValue(for: "$.owner.isAdmin").asBool()
91+
try json.getValue(for: "$.owner.isAdmin") == true
9292
)
9393
#expect(
94-
try json.getValue(for: "$.users[1].food").asString() == "chips"
94+
try json.getValue(for: "$.users[1].food") == "chips"
9595
)
9696
#expect(
97-
try json.getValue(for: "$.users[2].age").asNumber() == 9
97+
try json.getValue(for: "$.users[2].age") == 9
9898
)
9999
}
100100

0 commit comments

Comments
 (0)