Skip to content

Commit

Permalink
optic-to-tree conversion starts supporting Union{Nothing,T}
Browse files Browse the repository at this point in the history
  • Loading branch information
aplavin committed Dec 18, 2024
1 parent 4cab685 commit b589983
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 1 deletion.
14 changes: 14 additions & 0 deletions src/concatoptic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,15 @@ function tree_concatoptic(obj::Type, o::ComposedFunction)
end
concat(optics...)
end
# XXX: try to handle Union + maybe more uniformly
function tree_concatoptic(::Type{Union{Nothing,T}}, o::ComposedFunction) where {T}
inner_optic = tree_concatoptic(T, o.inner)
outer_obj_types = Core.Compiler.return_type(getall, Tuple{T, typeof(o.inner)}) |> _eltypes
optics = map(outer_obj_types, _optics(inner_optic)) do OT, oin
tree_concatoptic(OT, o.outer) maybe(oin)
end
concat(optics...)
end
tree_concatoptic(obj::Type, o::ConcatOptics) =
concat(map(o.optics) do oin
tree_concatoptic(obj, oin)
Expand All @@ -184,6 +193,11 @@ function tree_concatoptic(obj::Type{T}, o::Properties) where {T}
NT = Core.Compiler.return_type(getproperties, Tuple{T})
concat(map(PropertyLens, fieldnames(NT))...)
end
# XXX: try to handle Union + maybe more uniformly
function tree_concatoptic(::Type{Union{Nothing,T}}, ::Properties) where {T}
NT = Core.Compiler.return_type(getproperties, Tuple{T})
concat(map(maybePropertyLens, fieldnames(NT))...)
end

(a, b) = a b
# ∘₁(a::ConcatOptics{<:Tuple{Any}}, b) = only(a.optics) ∘₂ b
Expand Down
15 changes: 15 additions & 0 deletions test/concatoptic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,19 @@ end

@test tree_concatoptic(String, (@o _[ₚ])) === concat()
@test flat_concatoptic(String, (@o _[ₚ])) === concat()

o = tree_concatoptic(Union{Nothing, @NamedTuple{a::Int64, b::Float64}}, (@o _[ₚ]))
@test getall(nothing, o) === (nothing, nothing)
@test getall((a=1, b=2.0), o) === (1, 2.0)

o = tree_concatoptic(Union{Nothing, @NamedTuple{a::Union{Nothing, @NamedTuple{b::Int64, c::String}}}}, (@o _[ₚ][ₚ]))
@test getall(nothing, o) === (nothing, nothing)
@test getall((a=nothing,), o) === (nothing, nothing)
@test getall((a=(b=1, c="2"),), o) === (1, "2")

os = flat_concatoptic(Union{Nothing, @NamedTuple{a::Int64, b::Float64}}, (@o _[ₚ])) |> AccessorsExtra._optics
@test os === ((@maybe _.a), (@maybe _.b))

os = flat_concatoptic(Union{Nothing, @NamedTuple{a::Union{Nothing, @NamedTuple{b::Int64}}}}, (@o _[ₚ][ₚ])) |> AccessorsExtra._optics
@test os === ((@maybe _.b) (@maybe _.a),)
end
4 changes: 4 additions & 0 deletions test/recursive.jl
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ end
@test tree_concatoptic(obj, RecursiveOfType(Number)) === (@o _.a) ++ (((@o _[1].c) ++ (@o _[2].c)) (@o _.bs))
@test tree_concatoptic(obj, RecursiveOfType(NamedTuple)) === identity

@test tree_concatoptic(@NamedTuple{a::Int64, b::Float64}, RecursiveOfType(Number)) === (@o _.a) ++ (@o _.b)
@test tree_concatoptic(Union{Nothing, @NamedTuple{a::Int64, b::Float64}}, RecursiveOfType(Number)) === (@maybe _.a) ++ (@maybe _.b)
@test tree_concatoptic(Union{Nothing, @NamedTuple{a::Union{Nothing, @NamedTuple{b::Int64, c::Float64, d::String}}}}, RecursiveOfType(Number)) === ((@maybe _.b) ++ (@maybe _.c)) (@maybe _.a)

@test flat_concatoptic((1,""), RecursiveOfType(Number)) === @o _[1]
@test_broken flat_concatoptic((a=1, b=[2,3], c=""), RecursiveOfType(Number)) === @o _.a _.b[]
@test flat_concatoptic((a=1, b=SVector(2,3), c=""), RecursiveOfType(Number)) === @o _.a _.b[1] _.b[2]
Expand Down
2 changes: 1 addition & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -408,5 +408,5 @@ end
CHL.@check()

using Aqua
Aqua.test_all(AccessorsExtra, piracies=false, ambiguities=false)
Aqua.test_all(AccessorsExtra, piracies=(;broken=true), ambiguities=(;broken=true), unbound_args=(;broken=true))
end

0 comments on commit b589983

Please sign in to comment.