Skip to content

Commit 949f6bd

Browse files
authored
Update Breadcrumb (#30)
1 parent 7ca694d commit 949f6bd

File tree

4 files changed

+79
-168
lines changed

4 files changed

+79
-168
lines changed

Sources/JAYSON/JSON+CustomString.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ extension JSON: CustomStringConvertible, CustomDebugStringConvertible {
1616

1717
return
1818
[
19-
"Path: \(currentPath().description)",
2019
"SourceType: \(sourceType.description)",
2120
"Source:",
2221
"\(_data.flatMap { String(data: $0, encoding: .utf8) } ?? "<empty>")",

Sources/JAYSON/JSON+OptionalProperty.swift

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ extension JSON {
2727
public var dictionary: [String : JSON]? {
2828
return (source as? [String : Any])?.reduce([String : JSON]()) { dic, element in
2929
var dic = dic
30-
dic[element.key] = JSON(source: element.value, breadcrumb: Breadcrumb(json: self, key: element.key))
30+
dic[element.key] = JSON(source: element.value, breadcrumb: nil)
3131
return dic
3232
}
3333
}
@@ -36,10 +36,7 @@ extension JSON {
3636
return (source as? [Any])?
3737
.enumerated()
3838
.map {
39-
JSON(
40-
source: $0.element,
41-
breadcrumb: Breadcrumb(json: self, index: $0.offset)
42-
)
39+
JSON(source: $0.element, breadcrumb: nil)
4340
}
4441
}
4542

Sources/JAYSON/JSON.swift

Lines changed: 32 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -119,44 +119,45 @@ public struct JSON: Hashable, Sendable {
119119
}
120120

121121
public func currentPath() -> String {
122-
123-
var path: String = ""
124-
125-
var currentBreadcrumb: Breadcrumb? = breadcrumb
126-
127-
while let _currentBreadcrumb = currentBreadcrumb {
128-
path = _currentBreadcrumb.path + path
129-
currentBreadcrumb = _currentBreadcrumb.json.breadcrumb
130-
}
131-
132-
return "Root->" + path
122+
return breadcrumb?.renderPath() ?? ""
133123
}
134124
}
135125

136126
extension JSON {
137127

138-
final class Breadcrumb: CustomStringConvertible, CustomDebugStringConvertible, Sendable {
139-
140-
let json: JSON
141-
let path: String
142-
143-
init(json: JSON, key: String) {
144-
self.json = json
145-
self.path = "[\"\(key)\"]"
128+
struct Breadcrumb: Sendable {
129+
130+
enum Component {
131+
case key(String)
132+
case index(Int)
146133
}
147-
148-
init(json: JSON, index: Int) {
149-
self.json = json
150-
self.path = "[\(index)]"
134+
135+
var component: [Component]
136+
137+
init(key: String) {
138+
component = [.key(key)]
151139
}
152-
153-
var description: String {
154-
return "\(path)"
140+
141+
init(index: Int) {
142+
component = [.index(index)]
143+
}
144+
145+
consuming func appending(_ component: Component) -> Self {
146+
self.component.append(component)
147+
return self
155148
}
156-
157-
var debugDescription: String {
158-
return "\(path)\n\(json)"
149+
150+
func renderPath() -> String {
151+
return component.map { c in
152+
switch c {
153+
case .key(let key):
154+
return "[\"\(key)\"]"
155+
case .index(let index):
156+
return "[\(index)]"
157+
}
158+
}.joined()
159159
}
160+
160161
}
161162
}
162163

@@ -187,7 +188,7 @@ extension JSON {
187188
}
188189
return value
189190
}
190-
.map { JSON(source: $0, breadcrumb: Breadcrumb(json: self, key: key)) }
191+
.map { JSON(source: $0, breadcrumb: breadcrumb?.appending(.key(key)) ?? Breadcrumb(key: key)) }
191192
}
192193
set {
193194
set(any: newValue?.source, for: key)
@@ -204,7 +205,7 @@ extension JSON {
204205
}
205206
return nil
206207
}
207-
.map { JSON(source: $0, breadcrumb: Breadcrumb(json: self, index: index)) } ?? JSON.null
208+
.map { JSON(source: $0, breadcrumb: breadcrumb?.appending(.index(index)) ?? Breadcrumb(index: index)) } ?? JSON.null
208209
}
209210
}
210211
}
@@ -285,13 +286,6 @@ extension JSON {
285286
return try next(key.rawValue)
286287
}
287288

288-
/**
289-
if `self` has parent JSON, return parent `JSON`, otherwise return `self`
290-
*/
291-
public func back() -> JSON {
292-
return breadcrumb?.json ?? self
293-
}
294-
295289
public func removed(_ key: String) -> JSON {
296290

297291
guard let _source = (source as? NSDictionary)?.mutableCopy() as? NSMutableDictionary else {
@@ -300,62 +294,6 @@ extension JSON {
300294
_source.removeObject(forKey: key)
301295
return try! JSON(any: _source)
302296
}
303-
304-
/**
305-
Returns a Boolean value that indicates if the key presents a value excepts null.
306-
*/
307-
@available(*, deprecated, renamed: "presentsValue")
308-
public func exists(_ key: String...) -> Bool {
309-
presentsValue(key)
310-
}
311-
312-
/**
313-
Returns a Boolean value that indicates if the key presents a value excepts null.
314-
*/
315-
@available(*, deprecated, renamed: "presentsValue")
316-
public func exists(_ index: Int) -> Bool {
317-
presentsValue(index)
318-
}
319-
320-
/**
321-
Returns a Boolean value that indicates if the key presents a value excepts null.
322-
*/
323-
@available(*, deprecated, renamed: "contains")
324-
public func presentsValue(_ key: String...) -> Bool {
325-
presentsValue(key)
326-
}
327-
328-
/**
329-
Returns a Boolean value that indicates if the key presents a value excepts null.
330-
*/
331-
@available(*, deprecated, renamed: "contains")
332-
public func presentsValue(_ keys: [String]) -> Bool {
333-
do {
334-
let r = try _next(keys)
335-
guard case .null = r.sourceType else {
336-
return true
337-
}
338-
return false
339-
} catch {
340-
return false
341-
}
342-
}
343-
344-
/**
345-
Returns a Boolean value that indicates if the key presents a value excepts null.
346-
*/
347-
@available(*, deprecated, renamed: "contains")
348-
public func presentsValue(_ index: Int) -> Bool {
349-
do {
350-
let r = try next(index)
351-
guard case .null = r.sourceType else {
352-
return true
353-
}
354-
return false
355-
} catch {
356-
return false
357-
}
358-
}
359297

360298
/**
361299
Returns a Boolean value that indicates if the key contains a value (including NSNull).

Tests/JAYSONTests/Tests.swift

Lines changed: 45 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import XCTest
55

66
class Tests: XCTestCase {
77

8-
let inData = try! Data(contentsOf: Bundle.module.url(forResource: "Fixtures/test", withExtension: "json")!)
8+
let inData = try! Data(
9+
contentsOf: Bundle.module.url(forResource: "Fixtures/test", withExtension: "json")!)
910

1011
override func setUp() {
1112
super.setUp()
@@ -36,12 +37,12 @@ class Tests: XCTestCase {
3637

3738
func testEqualable() {
3839

39-
let source: [String : JSON] = [
40-
"aaa":"AAA",
41-
"bbb":["BBB":"AAA"],
42-
"a":[1,2,3],
43-
"enum":Enum.a.json,
44-
]
40+
let source: [String: JSON] = [
41+
"aaa": "AAA",
42+
"bbb": ["BBB": "AAA"],
43+
"a": [1, 2, 3],
44+
"enum": Enum.a.json,
45+
]
4546

4647
let json = JSON(source)
4748
let json2 = JSON(source)
@@ -51,12 +52,12 @@ class Tests: XCTestCase {
5152

5253
func testDictionaryInit() {
5354

54-
let dictionary: [AnyHashable : Any] = [
55-
"title" : "foo",
56-
"name" : "hiroshi",
57-
"age" : 25,
58-
"height" : 173,
59-
]
55+
let dictionary: [AnyHashable: Any] = [
56+
"title": "foo",
57+
"name": "hiroshi",
58+
"age": 25,
59+
"height": 173,
60+
]
6061

6162
do {
6263
let json = try JSON(any: dictionary)
@@ -67,38 +68,38 @@ class Tests: XCTestCase {
6768
}
6869
}
6970

70-
func testURLInit() {
71-
let dictionary = [
72-
"url" : "https://antoine.marandon.fr",
73-
]
74-
do {
75-
let json = try JSON(any: dictionary)
76-
let data = try json.data()
77-
let parsedJson = try JSON(data: data)
78-
XCTAssertEqual(dictionary["url"], try parsedJson.next("url").getURL().absoluteString)
79-
} catch {
80-
XCTFail("\(error)")
81-
}
82-
71+
func testURLInit() {
72+
let dictionary = [
73+
"url": "https://antoine.marandon.fr"
74+
]
75+
do {
76+
let json = try JSON(any: dictionary)
77+
let data = try json.data()
78+
let parsedJson = try JSON(data: data)
79+
XCTAssertEqual(dictionary["url"], try parsedJson.next("url").getURL().absoluteString)
80+
} catch {
81+
XCTFail("\(error)")
8382
}
8483

84+
}
85+
8586
func testIsArray() {
8687

8788
let json = JSON([
88-
128,129,130,
89-
])
89+
128, 129, 130,
90+
])
9091
XCTAssert(json.isArray)
9192
}
9293

9394
func testIsDictionary() {
9495

9596
let json = JSON(
9697
[
97-
"aaa":"AAA",
98-
"bbb":["BBB":"AAA"],
99-
"a":[1,2,3],
100-
"enum":Enum.a.json,
101-
]
98+
"aaa": "AAA",
99+
"bbb": ["BBB": "AAA"],
100+
"a": [1, 2, 3],
101+
"enum": Enum.a.json,
102+
]
102103
)
103104
XCTAssert(json.isDictionary)
104105
}
@@ -107,13 +108,12 @@ class Tests: XCTestCase {
107108

108109
let j = try! JSON(data: inData)
109110

110-
XCTAssert(j.presentsValue(13) == false)
111-
XCTAssert(j.presentsValue("a") == false)
112-
XCTAssert(j.presentsValue("b") == false)
113-
XCTAssert(j.presentsValue("a.b.c") == false)
114-
XCTAssert(j.presentsValue("tree1.tree2") == true)
115-
XCTAssert(j.presentsValue("tree1", "tree2") == true)
116-
XCTAssert(j.presentsValue("tree1") == true)
111+
XCTAssert(j.contains(13) == false)
112+
XCTAssert(j.contains("a") == false)
113+
XCTAssert(j.contains("b") == false)
114+
XCTAssert(j.contains("a.b.c") == false)
115+
XCTAssert(j.contains("tree1", "tree2") == true)
116+
XCTAssert(j.contains("tree1") == true)
117117

118118
}
119119

@@ -130,7 +130,7 @@ class Tests: XCTestCase {
130130
let j = try JSON(data: inData)
131131

132132
do {
133-
_ = try j.next("a").next("b").next("c")
133+
let _ = try j.next("a").next("b").next("c")
134134
XCTFail()
135135
} catch {
136136
print("Success \(error)")
@@ -143,6 +143,7 @@ class Tests: XCTestCase {
143143

144144
let j = try JSON(data: inData)
145145
let v = try j.next("tree1.tree2.tree3").next(0).next("index")
146+
XCTAssertEqual(v.currentPath(), #"["tree1"]["tree2"]["tree3"][0]["index"]"#)
146147
XCTAssertEqual(v, "myvalue")
147148
} catch {
148149
XCTFail("\(error)")
@@ -168,30 +169,6 @@ class Tests: XCTestCase {
168169
}
169170
}
170171

171-
func testBack() {
172-
173-
do {
174-
let j = try JSON(data: inData)
175-
let value = try j
176-
.next("tree1")
177-
.next("tree2")
178-
.back()
179-
.next("tree2")
180-
.back()
181-
.back()
182-
.next("tree1")
183-
.next("tree2")
184-
.next("tree3")
185-
.next(0)
186-
.next("index")
187-
.getString()
188-
189-
XCTAssertEqual(value, "myvalue")
190-
} catch {
191-
XCTFail("\(error)")
192-
}
193-
}
194-
195172
func testBuild() {
196173
var j = JSON()
197174
j["number"] = 124
@@ -200,11 +177,11 @@ class Tests: XCTestCase {
200177
j["null"] = JSON.null
201178
j["tree1"] = JSON(
202179
[
203-
"tree2" : JSON(
180+
"tree2": JSON(
204181
[
205-
"tree3" : JSON(
182+
"tree3": JSON(
206183
[
207-
JSON(["index" : "myvalue"])
184+
JSON(["index": "myvalue"])
208185
]
209186
)
210187
]

0 commit comments

Comments
 (0)