-
Notifications
You must be signed in to change notification settings - Fork 2
/
setters.jl
50 lines (36 loc) · 997 Bytes
/
setters.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
abstract type Setter <: KaleidoLens end
Setfield.get(::Any, setter::Setter) = error("Setters do not support `get`.")
struct NullSetter <: Setter end
Setfield.set(obj, ::NullSetter, ::Any) = obj
"""
nullsetter :: Setter
A setter that does nothing; i.e., `set(x, nullsetter, y) === x` for any
`x` and `y`.
# Examples
```jldoctest
julia> using Setfield, Kaleido
julia> set(1, nullsetter, 2)
1
```
"""
const nullsetter = NullSetter()
Base.show(io::IO, ::NullSetter) = print(io, "nullsetter")
# TODO: handle prefix
"""
ToField(f) :: Setter
Apply `f` when setting. Use `x -> get(x, f)` if `f` is a `Lens`.
# Examples
```jldoctest
julia> using Setfield, Kaleido
julia> setter = (@lens _.x) ∘ ToField(@lens _.a)
(@lens _.x) ∘ (←(@lens _.a)|❌→)
julia> set((x = 1, y = 2), setter, (a = 10, b = 20))
(x = 10, y = 2)
```
"""
struct ToField{F} <: Setter
f::F
end
_eval(f, x) = f(x)
_eval(f::Lens, x) = get(x, f)
Setfield.set(::Any, setter::ToField, x) = _eval(setter.f, x)