@@ -133,8 +133,6 @@ struct ConstructIfChanged{C}
133133 constructor:: C
134134end
135135
136- _constructor (x, t) = _constructor (x. handler, t)
137-
138136# TODO what do we call these things?
139137struct Construct end
140138_constructor (:: Construct , :: Type{T} ) where T = constructorof (T)
@@ -251,19 +249,6 @@ function modify(f, obj, w::If)
251249 end
252250end
253251
254- struct Select{C}
255- select_condition:: C
256- end
257- OpticStyle (:: Type{<:If} ) = ModifyBased ()
258-
259- function modify (f, obj, w:: If )
260- if w. modify_condition (obj)
261- (obj,)
262- else
263- ()
264- end
265- end
266-
267252"""
268253 mapproperties(f, obj)
269254
@@ -280,7 +265,7 @@ julia> Accessors.mapproperties(x -> x+1, obj)
280265```
281266$EXPERIMENTAL
282267"""
283- function mapproperties (f, obj:: O , optic , itr:: Nothing = nothing ) where O
268+ function mapproperties (f, obj:: O , handler = Construct () , itr:: Nothing = nothing ) where O
284269 # TODO move this helper elsewhere?
285270 pnames = propertynames (obj)
286271 if isempty (pnames)
@@ -290,11 +275,11 @@ function mapproperties(f, obj::O, optic, itr::Nothing=nothing) where O
290275 new_props = map (pnames) do p
291276 f (getproperty (obj, p))
292277 end
293- ctr = _constructor (optic , O)
278+ ctr = _constructor (handler , O)
294279 return ctr (new_props... )
295280 end
296281end
297- function mapproperties (f, obj:: O , optic , itr:: Int ) where O
282+ function mapproperties (f, obj:: O , handler , itr:: Int ) where O
298283 pnames = propertynames (obj)
299284 if isempty (pnames)
300285 return _maybeitr (obj, itr)
@@ -304,7 +289,7 @@ function mapproperties(f, obj::O, optic, itr::Int) where O
304289 val, itr = f (getproperty (obj, p), itr)
305290 (vals... , val), itr
306291 end
307- ctr = _constructor (optic , O)
292+ ctr = _constructor (handler , O)
308293 return _maybeitr (ctr (new_props... ), itr)
309294 end
310295end
@@ -330,10 +315,7 @@ Based on [`mapproperties`](@ref).
330315
331316$EXPERIMENTAL
332317"""
333- struct Properties{H}
334- handler:: H
335- end
336- Properties () = Properties (Construct ())
318+ struct Properties end
337319OpticStyle (:: Type{<:Properties} ) = ModifyBased ()
338320modify (f, o, :: Properties ) = mapproperties (f, o)
339321
@@ -353,7 +335,7 @@ julia> Accessors.mapfields(x -> x+1, obj)
353335```
354336$EXPERIMENTAL
355337"""
356- @generated function mapfields (f, obj:: O , optic , itr:: I = nothing ) where {O,H,I}
338+ @generated function mapfields (f, obj:: O , handler :: H = Construct () , itr:: I = nothing ) where {O,H,I}
357339 # TODO : This is how Flatten.jl works, but it's not really
358340 # correct use of ConstructionBase as it assumers properties=fields
359341 fnames = fieldnames (O)
@@ -424,12 +406,9 @@ Based on [`mapfields`](@ref).
424406
425407$EXPERIMENTAL
426408"""
427- struct Fields{H}
428- handler:: H
429- end
430- Fields () = Fields (Construct ())
409+ struct Fields end
431410OpticStyle (:: Type{<:Fields} ) = ModifyBased ()
432- modify (f, o, optic :: Fields ) = mapfields (f, o, optic )
411+ modify (f, o, :: Fields ) = mapfields (f, o)
433412
434413"""
435414 Recursive(descent_condition, optic)
@@ -528,18 +507,22 @@ julia> modify(x -> 100x, obj, Recursive(x -> (x isa Tuple), Elements()))
528507```
529508$EXPERIMENTAL
530509"""
531- struct Query{Select,Descend,Optic}
510+ struct Query{Select,Descend,Optic<: Union{ComposedOptic,Fields,Properties} }
532511 select_condition:: Select
533512 descent_condition:: Descend
534513 optic:: Optic
535514end
536515Query (select, descend = x -> true ) = Query (select, descend, Fields ())
537516Query (; select= Any, descend= x -> true , optic= Fields ()) = Query (select, descend, optic)
538517
518+ _inner (optic:: ComposedOptic ) = optic. inner
519+ _inner (optic:: Fields ) = optic
520+ _inner (optic:: Properties ) = optic
521+
539522function (q:: Query )(obj)
540- _query (obj, q. optic, Splat (), nothing ) do o
523+ _query (obj, _inner ( q. optic) , Splat (), nothing ) do o
541524 if q. select_condition (o)
542- (o ,)
525+ (_getouter (o, q . optic) ,)
543526 elseif q. descent_condition (o)
544527 q (o)
545528 else
@@ -548,12 +531,15 @@ function (q::Query)(obj)
548531 end
549532end
550533
534+ _getouter (o, optic:: ComposedOptic ) = optic. outer (o)
535+ _getouter (o, optic) = o
536+
551537_set (obj, q:: Query , val, :: SetBased ) = _setquery (obj, q:: Query , (val, 1 ))[1 ]
552538
553539function _setquery (obj, q:: Query , (val, itr))
554- _query (obj, q. optic, Construct (), itr) do o, itr
540+ _query (obj, _inner ( q. optic) , Construct (), itr) do o, itr
555541 if q. select_condition (o)
556- val[itr], itr + 1
542+ _setouter (o, q . optic, val[itr]) , itr + 1
557543 elseif q. descent_condition (o)
558544 _setquery (o, q, (val, itr))
559545 else
@@ -562,8 +548,10 @@ function _setquery(obj, q::Query, (val, itr))
562548 end
563549end
564550
551+ _setouter (o, optic:: ComposedOptic , v) = set (o, optic. outer, v)
552+ _setouter (o, optic, v) = v
553+
565554modify (f, obj, q:: Query ) = set (obj, q, map (f, q (obj)))
566555
567- _query (f, o, :: Elements , itr) = map (f, o)
568- _query (f, o, :: Fields , itr) = mapfields (f, o, itr)
569- _query (f, o, :: Properties , itr) = mapproperties (f, o, itr)
556+ _query (f, o, :: Fields , handler, itr) = mapfields (f, o, handler, itr)
557+ _query (f, o, :: Properties , handler, itr) = mapproperties (f, o, handler, itr)
0 commit comments