Strapping.jl icon indicating copy to clipboard operation
Strapping.jl copied to clipboard

Support Union types

Open chris-b1 opened this issue 4 years ago • 1 comments

Example below - StructTypes seems to handle this, so probably just a little investigation to wire up the correct method, unless I'm doing something wrong here.

import StructTypes, Strapping

struct Thing
    a::String
    b::Union{Int, Nothing}
end
StructTypes.StructType(::Type{Thing}) = StructTypes.Struct()

# works
julia> StructTypes.constructfrom(Thing, Dict(:a => "Dog", :b => nothing))
Thing("Dog", nothing)

# errors 
julia> Strapping.construct(Thing, [(; a = "Dog", b = nothing) ])
ERROR: ArgumentError: type does not have a definite number of fields
Stacktrace:
  [1] fieldcount(t::Any)
    @ Base .\reflection.jl:707
  [2] construct
    @ ~\.julia\packages\StructTypes\dN2cf\src\StructTypes.jl:573 [inlined]
  [3] construct(::StructTypes.UnorderedStruct, ::Type{Union{Nothing, Int64}}, row::NamedTuple{(:a, :b), Tuple{String, Int64}}, prefix::Symbol, offset::Base.RefValue{Int64}; kw::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Strapping ~\.julia\packages\Strapping\uLJ7i\src\Strapping.jl:149
  [4] construct(::StructTypes.UnorderedStruct, ::Type{Union{Nothing, Int64}}, row::NamedTuple{(:a, :b), Tuple{String, Int64}}, prefix::Symbol, offset::Base.RefValue{Int64})
    @ Strapping ~\.julia\packages\Strapping\uLJ7i\src\Strapping.jl:149
  [5] construct(::StructTypes.UnorderedStruct, ::Type{Union{Nothing, Int64}}, row::NamedTuple{(:a, :b), Tuple{String, Int64}}, prefix::Symbol, offset::Base.RefValue{Int64}, i::Int64, nm::Symbol; kw::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Strapping ~\.julia\packages\Strapping\uLJ7i\src\Strapping.jl:158
  [6] construct(::StructTypes.UnorderedStruct, ::Type{Union{Nothing, Int64}}, row::NamedTuple{(:a, :b), Tuple{String, Int64}}, prefix::Symbol, offset::Base.RefValue{Int64}, i::Int64, nm::Symbol)
    @ Strapping ~\.julia\packages\Strapping\uLJ7i\src\Strapping.jl:158
  [7] (::Strapping.var"#104#105"{Thing, Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, NamedTuple{(:a, :b), Tuple{String, Int64}}, Symbol, Base.RefValue{Int64}})(i::Int64, nm::Symbol, TT::Type)
    @ Strapping ~\.julia\packages\Strapping\uLJ7i\src\Strapping.jl:150
  [8] construct
    @ ~\.julia\packages\StructTypes\dN2cf\src\StructTypes.jl:584 [inlined]
  [9] construct(::StructTypes.UnorderedStruct, ::Type{Thing}, row::NamedTuple{(:a, :b), Tuple{String, Int64}}, prefix::Symbol, offset::Base.RefValue{Int64}; kw::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Strapping ~\.julia\packages\Strapping\uLJ7i\src\Strapping.jl:149
 [10] construct(::StructTypes.UnorderedStruct, ::Type{Thing}, row::NamedTuple{(:a, :b), Tuple{String, Int64}}, prefix::Symbol, offset::Base.RefValue{Int64}) (repeats 2 times)
    @ Strapping ~\.julia\packages\Strapping\uLJ7i\src\Strapping.jl:149
 [11] construct(::Type{Thing}, rows::Vector{NamedTuple{(:a, :b), Tuple{String, Int64}}}, row::NamedTuple{(:a, :b), Tuple{String, Int64}}, st::Int64; kw::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Strapping ~\.julia\packages\Strapping\uLJ7i\src\Strapping.jl:118
 [12] construct(::Type{Thing}, rows::Vector{NamedTuple{(:a, :b), Tuple{String, Int64}}}, row::NamedTuple{(:a, :b), Tuple{String, Int64}}, st::Int64)
    @ Strapping ~\.julia\packages\Strapping\uLJ7i\src\Strapping.jl:118
 [13] construct(::Type{Thing}, source::Vector{NamedTuple{(:a, :b), Tuple{String, Int64}}}; silencewarnings::Bool, kw::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Strapping ~\.julia\packages\Strapping\uLJ7i\src\Strapping.jl:99
 [14] construct(::Type{Thing}, source::Vector{NamedTuple{(:a, :b), Tuple{String, Int64}}})
    @ Strapping ~\.julia\packages\Strapping\uLJ7i\src\Strapping.jl:95
 [15] top-level scope
    @ REPL[21]:1

chris-b1 avatar Oct 25 '21 20:10 chris-b1

I can confirm this. eg :

using Dates, Strapping
mutable struct Mytype
    id::Int
    user2::String
    sent::Bool
    body::Union{Array{String}, String}
    timestamp::DateTime
end

mtp = Mytype("1", "foo", true, "hi", Dates.now())

a = Strapping.deconstruct(msg)
a.names
4-element Vector{Symbol}:
 :id
 :user2
 :sent
 :timestamp

Sov-trotter avatar Oct 27 '21 13:10 Sov-trotter