@@ -249,8 +249,36 @@ function modify(f, obj, w::If)
249249 end
250250end
251251
252+ abstract type ObjectMap end
253+
254+ OpticStyle (:: Type{<:ObjectMap} ) = ModifyBased ()
255+ modify (f, o, optic:: ObjectMap ) = mapobject (f, o, optic, Construct, nothing )
256+
257+ """
258+ Properties()
259+
260+ Access all properties of an objects.
261+
262+ ```jldoctest
263+ julia> using Accessors
264+
265+ julia> obj = (a=1, b=2, c=3)
266+ (a = 1, b = 2, c = 3)
267+
268+ julia> set(obj, Properties(), "hi")
269+ (a = "hi", b = "hi", c = "hi")
270+
271+ julia> modify(x -> 2x, obj, Properties())
272+ (a = 2, b = 4, c = 6)
273+ ```
274+ Based on [`mapobject`](@ref).
275+
276+ $EXPERIMENTAL
277+ """
278+ struct Properties <: ObjectMap end
279+
252280"""
253- mapproperties (f, obj)
281+ mapobject (f, obj)
254282
255283Construct a copy of `obj`, with each property replaced by
256284the result of applying `f` to it.
@@ -260,82 +288,63 @@ julia> using Accessors
260288
261289julia> obj = (a=1, b=2);
262290
263- julia> Accessors.mapproperties (x -> x+1, obj)
291+ julia> Accessors.mapobject (x -> x+1, obj)
264292(a = 2, b = 3)
265293```
266294$EXPERIMENTAL
267295"""
268- function mapproperties (f, obj:: O , handler= Construct () , itr:: Nothing = nothing ) where O
296+ function mapobject (f, obj:: O , :: Properties , handler, itr:: Nothing ) where O
269297 # TODO move this helper elsewhere?
270298 pnames = propertynames (obj)
271299 if isempty (pnames)
272300 return obj
273301 else
274- ctor = constructorof (typeof (obj))
275302 new_props = map (pnames) do p
276303 f (getproperty (obj, p))
277304 end
278305 ctr = _constructor (handler, O)
279306 return ctr (new_props... )
280307 end
281308end
282- function mapproperties (f, obj:: O , handler, itr:: Int ) where O
309+ function mapobject (f, obj:: O , :: Properties , handler, itr:: Int ) where O
283310 pnames = propertynames (obj)
284311 if isempty (pnames)
285- return _maybeitr ( obj, itr)
312+ return obj, itr
286313 else
287314 # TODO : this is too slow
288315 new_props, itr = reduce (pnames; init= ((), itr)) do (vals, itr), p
289316 val, itr = f (getproperty (obj, p), itr)
290317 (vals... , val), itr
291318 end
292319 ctr = _constructor (handler, O)
293- return _maybeitr ( ctr (new_props... ), itr)
320+ return ctr (new_props... ), itr
294321 end
295322end
296323
297324"""
298- Properties ()
325+ Fields ()
299326
300- Access all properties of an objects.
327+ Access all fields of an objects.
301328
302329```jldoctest
303330julia> using Accessors
304331
305332julia> obj = (a=1, b=2, c=3)
306333(a = 1, b = 2, c = 3)
307334
308- julia> set(obj, Properties (), "hi")
335+ julia> set(obj, Fields (), "hi")
309336(a = "hi", b = "hi", c = "hi")
310337
311- julia> modify(x -> 2x, obj, Properties ())
338+ julia> modify(x -> 2x, obj, Fields ())
312339(a = 2, b = 4, c = 6)
313340```
314- Based on [`mapproperties `](@ref).
341+ Based on [`mapfields `](@ref).
315342
316343$EXPERIMENTAL
317344"""
318- struct Properties end
319- OpticStyle (:: Type{<:Properties} ) = ModifyBased ()
320- modify (f, o, :: Properties ) = mapproperties (f, o)
321-
322- """
323- mapfields(f, obj)
324-
325- Construct a copy of `obj`, with each fields replaced by
326- the result of applying `f` to it.
327-
328- ```jldoctest
329- julia> using Accessors
330-
331- julia> obj = (a=1, b=2);
345+ struct Fields <: ObjectMap end
332346
333- julia> Accessors.mapfields(x -> x+1, obj)
334- (a = 2, b = 3)
335- ```
336- $EXPERIMENTAL
337- """
338- @generated function mapfields (f, obj:: O , handler:: H = Construct (), itr:: I = nothing ) where {O,H,I}
347+ @generated function mapobject (f, obj:: O , :: Fields , handler:: H = Construct (), itr:: I = nothing ) where {O,H,I}
339348 # TODO : This is how Flatten.jl works, but it's not really
340349 # correct use of ConstructionBase as it assumers properties=fields
341350 fnames = fieldnames (O)
385394_maybeitr (x, :: Nothing ) = x
386395_maybeitr (x, itr) = x, itr
387396
388- """
389- Fields()
390-
391- Access all fields of an objects.
392-
393- ```jldoctest
394- julia> using Accessors
395-
396- julia> obj = (a=1, b=2, c=3)
397- (a = 1, b = 2, c = 3)
398-
399- julia> set(obj, Fields(), "hi")
400- (a = "hi", b = "hi", c = "hi")
401-
402- julia> modify(x -> 2x, obj, Fields())
403- (a = 2, b = 4, c = 6)
404- ```
405- Based on [`mapfields`](@ref).
406-
407- $EXPERIMENTAL
408- """
409- struct Fields end
410- OpticStyle (:: Type{<:Fields} ) = ModifyBased ()
411- modify (f, o, :: Fields ) = mapfields (f, o)
412-
413397"""
414398 Recursive(descent_condition, optic)
415399
@@ -484,11 +468,10 @@ Base.@propagate_inbounds function set(obj, lens::DynamicIndexLens, val)
484468end
485469
486470"""
487- Query(select, ignore )
471+ Query(select, descend )
488472
489- Query an object recursively, choosing fields based on the single-argument
490- function `select` and ignoring objects based on another single-argument
491- function `ignore`.
473+ Query an object recursively, choosing fields when `select`
474+ returns `true`, and descending when `descend`.
492475
493476```jldoctest
494477julia> using Accessors
@@ -515,43 +498,37 @@ end
515498Query (select, descend = x -> true ) = Query (select, descend, Fields ())
516499Query (; select= Any, descend= x -> true , optic= Fields ()) = Query (select, descend, optic)
517500
518- _inner (optic:: ComposedOptic ) = optic. inner
519- _inner (optic:: Fields ) = optic
520- _inner (optic:: Properties ) = optic
521-
522501function (q:: Query )(obj)
523- _query (obj, _inner (q. optic), Splat (), nothing ) do o
502+ mapobject (obj, _inner (q. optic), Splat (), nothing ) do o
524503 if q. select_condition (o)
525504 (_getouter (o, q. optic),)
526505 elseif q. descent_condition (o)
527- q (o)
506+ q (o) # also a tuple
528507 else
529508 ()
530509 end
531510 end
532511end
533512
534- _getouter (o, optic:: ComposedOptic ) = optic. outer (o)
535- _getouter (o, optic) = o
536-
537- _set (obj, q:: Query , val, :: SetBased ) = _setquery (obj, q:: Query , (val, 1 ))[1 ]
513+ set (obj, q:: Query , vals) = _set (obj, q:: Query , (vals, 1 ))[1 ]
538514
539- function _setquery (obj, q:: Query , (val , itr))
540- _query (obj, _inner (q. optic), Construct (), itr) do o, itr
515+ function _set (obj, q:: Query , (vals , itr))
516+ mapobject (obj, _inner (q. optic), Construct (), itr) do o, itr
541517 if q. select_condition (o)
542- _setouter (o, q. optic, val [itr]), itr + 1
518+ _setouter (o, q. optic, vals [itr]), itr + 1
543519 elseif q. descent_condition (o)
544- _setquery (o, q, (val , itr))
520+ _set (o, q, (vals , itr))
545521 else
546522 o, itr
547523 end
548524 end
549525end
550526
551- _setouter (o, optic:: ComposedOptic , v) = set (o, optic. outer, v)
552- _setouter (o, optic, v) = v
553-
554527modify (f, obj, q:: Query ) = set (obj, q, map (f, q (obj)))
555528
556- _query (f, o, :: Fields , handler, itr) = mapfields (f, o, handler, itr)
557- _query (f, o, :: Properties , handler, itr) = mapproperties (f, o, handler, itr)
529+ _inner (optic:: ComposedOptic ) = optic. inner
530+ _inner (optic) = optic
531+ _getouter (o, optic:: ComposedOptic ) = optic. outer (o)
532+ _getouter (o, optic) = o
533+ _setouter (o, optic:: ComposedOptic , v) = set (o, optic. outer, v)
534+ _setouter (o, optic, v) = v
0 commit comments