ancapdev / LightBSON.jl

High performance encoding and decoding of BSON data in Julia
MIT License
20 stars 4 forks source link

Support conversions in tuple's #27

Open green-nsk opened 1 year ago

green-nsk commented 1 year ago

Conversions API currently doesn't look inside tuples.

using LightBSON

struct X
    x::String
end

function Base.setindex!(writer::BSONWriter, value::X, index::Union{String, Symbol})
    GC.@preserve value setindex!(writer, UnsafeBSONString(pointer(value.x), length(value.x)), index)
end

LightBSON.bson_representation_type(::Type{X}) = UnsafeBSONString

buf = UInt8[]; writer = BSONWriter(buf); writer["x"] = X("foo"); close(writer)
reader = BSONReader(buf); reader["x"][X]

However this throws:

buf = UInt8[]; writer = BSONWriter(buf); writer["x"] = (X("foo"),); close(writer)
reader = BSONReader(buf); reader["x"][Tuple{X}]
ERROR: MethodError: Cannot `convert` an object of type String to an object of type X
Closest candidates are:
  convert(::Type{T}, ::T) where T at ~/distr/julia-1.7.3/share/julia/base/essentials.jl:218
  X(::String) at ~/code/scratch.jl:4
  X(::Any) at ~/code/scratch.jl:4
Stacktrace:
 [1] _totuple
   @ ./tuple.jl:330 [inlined]
 [2] Tuple{X}(itr::Vector{Any})
   @ Base ./tuple.jl:317
 [3] bson_representation_convert
   @ ~/.julia/packages/LightBSON/WrSYn/src/representations.jl:14 [inlined]

Defining Base.convert(::Type{X}, ::AbstractString) helps, but but it shouldn't be needed:

Base.convert(::Type{X}, v::AbstractString) = X(v)
reader = BSONReader(buf); reader["x"][Tuple{X}]