generated from quinnj/Example.jl
-
Notifications
You must be signed in to change notification settings - Fork 7
Open
Description
I have this test example to read/write complex tree structure into a simpler tree representation, so I use @nonstruct to force make to call lift/lower methods, as mentioned in docs. But looks like make does not call lower as expected.
MWE:
module Example
using StructUtils
using AbstractTrees
using OrderedCollections
abstract type PrintTree end
AbstractTrees.children(node::PrintTree) = node.children |> values
AbstractTrees.printnode(io::IO, node::PrintTree) = begin print(io, node.id, " => ", node.data) end
Base.show(io::IO, node::PrintTree) = AbstractTrees.print_tree(io, node)
@kwdef mutable struct DataNode <: PrintTree
id::String = ""
parent::Union{DataNode, Nothing} = nothing
children::OrderedDict{String, DataNode} = OrderedDict{String, DataNode}()
data::Any = nothing
end
function Base.setindex!(node::DataNode, child::DataNode, key)
node.children[key] = child
child.parent = node
child.id = key
return child
end
StructUtils.structlike(::Type{DataNode}) = false
function StructUtils.lift(::Type{DataNode}, src::T) where T
@info "lift"
node = DataNode()
if isprimitivetype(T) || T <: Union{AbstractString, Number, Bool}
node.data = src
elseif T <: AbstractDict
for (k, v) in src
node[string(k)] = StructUtils.lift(DataNode, v)
end
elseif isstructtype(T)
for k in fieldnames(T)
v = getfield(src, k)
node[string(k)] = StructUtils.lift(DataNode, v)
end
end
return node
end
function StructUtils.lower(node::DataNode)
@info "lower"
if isempty(node.children)
return node.data
end
result = OrderedDict{String,Any}()
for (k, child) in node.children
result[k] = StructUtils.lower(child)
end
return result
end
function test()
inp = OrderedDict{String, Any}("leaf" => 1)
node = StructUtils.lift(DataNode, inp)
@show node
node = StructUtils.make(DataNode, inp) # make calls lift
@show node
out = StructUtils.lower(node)
@show out
out = StructUtils.make(OrderedDict{String, Any}, node) # make does not call lower
@show out
return nothing
end
end
import .Example
Example.test()(Here I declare structlike = false instead of @nonstruct to have separate @kwdef functionality, but returning @nonstruct does not change the result.)
Output:
[ Info: lift
[ Info: lift
node = => nothing
└─ leaf => 1
[ Info: lift
[ Info: lift
node = => nothing
└─ leaf => 1
[ Info: lower
[ Info: lower
out = OrderedDict{String, Any}("leaf" => 1)
out = OrderedDict{String, Any}("id" => "", "parent" => nothing, "children" => OrderedDict{String, Main.Example.DataNode}("leaf" => leaf => 1
), "data" => nothing)
Metadata
Metadata
Assignees
Labels
No labels