Skip to content

Commit 556c9d7

Browse files
authored
Merge pull request rarestype#126 from rarestype/add-doccomments
[patch]: add doccomments, and a special case of `&`
2 parents 6e3a152 + b4610eb commit 556c9d7

2 files changed

Lines changed: 83 additions & 13 deletions

File tree

Sources/JQ/JSON.ArrayAccessor.swift

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,27 +29,61 @@ extension JSON.ArrayAccessor {
2929
}
3030
}
3131
extension JSON.ArrayAccessor {
32+
/// Modify an existing array at the accessed path, returning nil if no such array exists, or
33+
/// if the accessed path is invalid.
3234
@discardableResult
3335
@inlinable public static func &? <E, T>(
3436
self: inout Self,
3537
yield: (inout JSON.Array) throws(E) -> T
3638
) throws(E) -> T? {
39+
if case .occupied(var array) = self.state {
40+
self.state = .writable
41+
defer {
42+
self.state = .occupied(array)
43+
}
44+
return try yield(&array)
45+
} else {
46+
return nil
47+
}
48+
}
49+
50+
/// Modify the array at the accessed path, creating an empty array in the tree if it does
51+
/// not exist.
52+
///
53+
/// Use this when you are confident that the array must be written, and expect to receive
54+
/// an error if incompatible data already exists in the accessed location.
55+
@inlinable public static func & (
56+
self: inout Self,
57+
yield: (inout JSON.Array) throws -> ()
58+
) throws {
3759
switch self.state {
3860
case .protected:
39-
return nil
40-
case .reserved:
41-
return nil
61+
throw JSON.NodeAccessError.protected(self.crumb)
62+
63+
case .reserved(let offender):
64+
throw JSON.NodeAccessError.reserved(self.crumb, offender)
65+
4266
case .writable:
43-
return nil
44-
case .occupied(var array):
67+
var array: JSON.Array = []
68+
try yield(&array)
69+
self.state = .occupied(array)
70+
71+
case .occupied(let value):
72+
var array: JSON.Array = consume value
4573
self.state = .writable
4674
defer {
4775
self.state = .occupied(array)
4876
}
49-
return try yield(&array)
77+
try yield(&array)
5078
}
5179
}
5280

81+
/// Modify the array at the accessed path, allowing the closure to create, update, or delete
82+
/// it. Assigning a value to a node that was originally nil creates it, likewise,
83+
/// assigning nil to a node that was originally non-nil deletes it.
84+
///
85+
/// If the accessed path is not writable, and the node is assigned a value in the
86+
/// closure — even an empty array — a ``NodeAccessError`` is thrown.
5387
@inlinable public static func & (
5488
self: inout Self,
5589
yield: (inout JSON.Array?) throws -> ()
@@ -70,7 +104,7 @@ extension JSON.ArrayAccessor {
70104
}
71105

72106
case .writable:
73-
var array: JSON.Array? = []
107+
var array: JSON.Array? = nil
74108
try yield(&array)
75109
if let array: JSON.Array {
76110
self.state = .occupied(array)

Sources/JQ/JSON.NodeAccessor.swift

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ extension JSON.NodeAccessor {
160160
}
161161
}
162162
extension JSON.NodeAccessor {
163+
/// Delete the node at the accessed path, throwing a ``NodeAccessError`` if the location is
164+
/// not writable and data already exists there.
163165
@inlinable public static func &= (
164166
self: inout Self,
165167
delete: Never?
@@ -175,6 +177,8 @@ extension JSON.NodeAccessor {
175177
self.state = .writable
176178
}
177179
}
180+
/// Create or update the node at the accessed path, throwing a ``NodeAccessError`` if the
181+
/// location is not writable.
178182
@inlinable public static func &= (
179183
self: inout Self,
180184
value: consuming JSON.Node
@@ -191,27 +195,59 @@ extension JSON.NodeAccessor {
191195
}
192196
}
193197

198+
/// Modify an existing node at the accessed path, returning nil if no such node exists, or
199+
/// if the accessed path is invalid.
194200
@discardableResult
195201
@inlinable public static func &? <E, T>(
196202
self: inout Self,
197203
yield: (inout JSON.Node) throws(E) -> T
198204
) throws(E) -> T? {
205+
if case .occupied(var value) = self.state {
206+
self.state = .writable
207+
defer {
208+
self.state = .occupied(value)
209+
}
210+
return try yield(&value)
211+
} else {
212+
return nil
213+
}
214+
}
215+
216+
/// Modify the node at the accessed path, creating it with a default value of
217+
/// ``JSON.Node/null``, if it does not exist.
218+
///
219+
/// Use this when you are confident that the node must be written, and expect to receive
220+
/// an error if incompatible data already exists in the accessed location.
221+
@inlinable public static func & (
222+
self: inout Self,
223+
yield: (inout JSON.Node) throws -> ()
224+
) throws {
199225
switch self.state {
200226
case .protected:
201-
return nil
202-
case .reserved:
203-
return nil
227+
throw JSON.NodeAccessError.protected(self.crumb)
228+
case .reserved(let offender):
229+
throw JSON.NodeAccessError.reserved(self.crumb, offender)
204230
case .writable:
205-
return nil
206-
case .occupied(var value):
231+
var value: JSON.Node = .null
232+
try yield(&value)
233+
self.state = .occupied(value)
234+
235+
case .occupied(let value):
236+
var value: JSON.Node = consume value
207237
self.state = .writable
208238
defer {
209239
self.state = .occupied(value)
210240
}
211-
return try yield(&value)
241+
try yield(&value)
212242
}
213243
}
214244

245+
/// Modify the node at the accessed path, allowing the closure to create, update, or delete
246+
/// it. Assigning a value to a node that was originally nil creates it, likewise,
247+
/// assigning nil to a node that was originally non-nil deletes it.
248+
///
249+
/// If the accessed path is not writable, and the node is assigned a value in the
250+
/// closure — including an explicit ``JSON.Node/null`` — a ``NodeAccessError`` is thrown.
215251
@inlinable public static func & (
216252
self: inout Self,
217253
yield: (inout JSON.Node?) throws -> ()

0 commit comments

Comments
 (0)