@@ -133,6 +133,8 @@ struct ConstructIfChanged{C}
133
133
constructor:: C
134
134
end
135
135
136
+ _constructor (x, t) = _constructor (x. handler, t)
137
+
136
138
# TODO what do we call these things?
137
139
struct Construct end
138
140
_constructor (:: Construct , :: Type{T} ) where T = constructorof (T)
@@ -249,6 +251,19 @@ function modify(f, obj, w::If)
249
251
end
250
252
end
251
253
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
+
252
267
"""
253
268
mapproperties(f, obj)
254
269
@@ -265,24 +280,31 @@ julia> Accessors.mapproperties(x -> x+1, obj)
265
280
```
266
281
$EXPERIMENTAL
267
282
"""
268
- function mapproperties (f, obj:: O , handler = Construct () , itr= nothing ) where O
283
+ function mapproperties (f, obj:: O , optic , itr:: Nothing = nothing ) where O
269
284
# TODO move this helper elsewhere?
285
+ pnames = propertynames (obj)
286
+ if isempty (pnames)
287
+ return obj
288
+ else
289
+ ctor = constructorof (typeof (obj))
290
+ new_props = map (pnames) do p
291
+ f (getproperty (obj, p))
292
+ end
293
+ ctr = _constructor (optic, O)
294
+ return ctr (new_props... )
295
+ end
296
+ end
297
+ function mapproperties (f, obj:: O , optic, itr:: Int ) where O
270
298
pnames = propertynames (obj)
271
299
if isempty (pnames)
272
300
return _maybeitr (obj, itr)
273
301
else
274
302
# TODO : this is too slow
275
303
new_props, itr = reduce (pnames; init= ((), itr)) do (vals, itr), p
276
- prop = getproperty (obj, p)
277
- if itr isa Nothing
278
- val = f (prop)
279
- (vals... , val), itr
280
- else
281
- val, itr = f (prop, itr)
282
- (vals... , val), itr
283
- end
304
+ val, itr = f (getproperty (obj, p), itr)
305
+ (vals... , val), itr
284
306
end
285
- ctr = _constructor (handler , O)
307
+ ctr = _constructor (optic , O)
286
308
return _maybeitr (ctr (new_props... ), itr)
287
309
end
288
310
end
@@ -308,7 +330,10 @@ Based on [`mapproperties`](@ref).
308
330
309
331
$EXPERIMENTAL
310
332
"""
311
- struct Properties end
333
+ struct Properties{H}
334
+ handler:: H
335
+ end
336
+ Properties () = Properties (Construct ())
312
337
OpticStyle (:: Type{<:Properties} ) = ModifyBased ()
313
338
modify (f, o, :: Properties ) = mapproperties (f, o)
314
339
@@ -328,7 +353,7 @@ julia> Accessors.mapfields(x -> x+1, obj)
328
353
```
329
354
$EXPERIMENTAL
330
355
"""
331
- @generated function mapfields (f, obj:: O , handler :: H = Construct () , itr:: I = nothing ) where {O,H,I}
356
+ @generated function mapfields (f, obj:: O , optic , itr:: I = nothing ) where {O,H,I}
332
357
# TODO : This is how Flatten.jl works, but it's not really
333
358
# correct use of ConstructionBase as it assumers properties=fields
334
359
fnames = fieldnames (O)
@@ -350,23 +375,23 @@ $EXPERIMENTAL
350
375
end
351
376
new_prop_exp = Expr (:tuple , val_exps... )
352
377
end
353
- # ret = if H == MaybeConstruct
354
- # quote
378
+ ret = if H == MaybeConstruct
379
+ quote
355
380
# TODO : last type instability.
356
381
# replace this with val => Changed(), val => Unchanged()
357
382
# return values.
358
383
#
359
384
# Don't construct when we don't absolutely have to.
360
385
# `constructorof` may not be defined for an object.
361
- # if props === new_props
362
- # return obj, itr
363
- # else
364
- # return _maybeitr($ctr(new_props...), itr)
365
- # end
366
- # end
367
- # else
386
+ if props === new_props
387
+ return _maybeitr ( obj, itr)
388
+ else
389
+ return _maybeitr ($ ctr (new_props... ), itr)
390
+ end
391
+ end
392
+ else
368
393
ret = :(return _maybeitr ($ ctr (new_props... ), itr))
369
- # end
394
+ end
370
395
quote
371
396
props = $ prop_exp
372
397
new_props = $ new_prop_exp
@@ -399,9 +424,12 @@ Based on [`mapfields`](@ref).
399
424
400
425
$EXPERIMENTAL
401
426
"""
402
- struct Fields end
427
+ struct Fields{H}
428
+ handler:: H
429
+ end
430
+ Fields () = Fields (Construct ())
403
431
OpticStyle (:: Type{<:Fields} ) = ModifyBased ()
404
- modify (f, o, :: Fields ) = mapfields (f, o)
432
+ modify (f, o, optic :: Fields ) = mapfields (f, o, optic )
405
433
406
434
"""
407
435
Recursive(descent_condition, optic)
@@ -505,7 +533,7 @@ struct Query{Select,Descend,Optic}
505
533
descent_condition:: Descend
506
534
optic:: Optic
507
535
end
508
- Query (select, ignore = x -> true ) = Query (select, ignore , Fields ())
536
+ Query (select, descend = x -> true ) = Query (select, descend , Fields ())
509
537
Query (; select= Any, descend= x -> true , optic= Fields ()) = Query (select, descend, optic)
510
538
511
539
function (q:: Query )(obj)
@@ -534,6 +562,8 @@ function _setquery(obj, q::Query, (val, itr))
534
562
end
535
563
end
536
564
537
- _query (f, o, :: Elements , handler, itr) = map (f, o)
538
- _query (f, o, :: Fields , handler, itr) = mapfields (f, o, handler, itr)
539
- _query (f, o, :: Properties , handler, itr) = mapproperties (f, o, handler, itr)
565
+ modify (f, obj, q:: Query ) = set (obj, q, map (f, q (obj)))
566
+
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)
0 commit comments