Milliseconds and JSON3

Hi all :slight_smile:

I want to do a round trip. Converting Milliseconds to JSON and back. But I can’t get it to work. Only one way works. The code below is my example.

julia> using JSON3

julia> using StructTypes

julia> using Dates

julia> StructTypes.StructType(::Type{Millisecond}) = StructTypes.NumberType()

julia> StructTypes.construct(::Type{Millisecond}, x::Millisecond) = x.value

julia> StructTypes.numbertype(::Type{Millisecond}) = Millisecond

julia> JSON3.write(Millisecond(1))
"1"

# and now the other direction
julia> JSON3.read("1", Millisecond)
ERROR: MethodError: no method matching typeparser(::Type{Millisecond}, ::Base.CodeUnits{UInt8, String}, ::Int64, ::Int64, ::UInt8, ::Int16, ::Parsers.Options{false, false, false, false, Nothing, Nothing, Nothing})
Closest candidates are:
  typeparser(::Type{Bool}, ::Any, ::Any, ::Any, ::Any, ::Any, ::Parsers.Options{ignorerepeated, ignoreemptylines, Q, debug, S, 
D, DF}) where {ignorerepeated, ignoreemptylines, Q, debug, S, D, DF} at C:\Users\<user>\.julia\packages\Parsers\Vdwny\src\bools.jl:1
  typeparser(::Type{T}, ::Any, ::Any, ::Any, ::Any, ::Any, ::Parsers.Options{ignorerepeated, ignoreemptylines, Q, debug, S, D, 
DF}) where {T<:Integer, ignorerepeated, ignoreemptylines, Q, debug, S, D, DF} at C:\Users\<user>\.julia\packages\Parsers\Vdwny\src\ints.jl:7
  typeparser(::Type{T}, ::Any, ::Any, ::Any, ::Any, ::Any, ::Parsers.Options{ignorerepeated, ignoreemptylines, Q, debug, S, D, 
DF}) where {T<:Union{Float16, Float32, Float64, BigFloat}, ignorerepeated, ignoreemptylines, Q, debug, S, D, DF} at C:\Users\<user>\.julia\packages\Parsers\Vdwny\src\floats.jl:42
  ...
Stacktrace:
 [1] read(::StructTypes.NumberType, buf::Base.CodeUnits{UInt8, String}, pos::Int64, len::Int64, b::UInt8, ::Type{Millisecond}; 
parsequoted::Bool, kw::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ JSON3 C:\Users\<user>\.julia\packages\JSON3\VnoI3\src\structs.jl:174
 [2] read(::StructTypes.NumberType, buf::Base.CodeUnits{UInt8, String}, pos::Int64, len::Int64, b::UInt8, ::Type{Millisecond}) 
   @ JSON3 C:\Users\<user>\.julia\packages\JSON3\VnoI3\src\structs.jl:166
 [3] read(str::String, ::Type{Millisecond}; kw::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})      
   @ JSON3 C:\Users\<user>\.julia\packages\JSON3\VnoI3\src\structs.jl:34
 [4] read(str::String, ::Type{Millisecond})
   @ JSON3 C:\Users\<user>\.julia\packages\JSON3\VnoI3\src\structs.jl:33
 [5] top-level scope
   @ REPL[11]:1


# changing the definition from above...
julia> StructTypes.numbertype(::Type{Millisecond}) = Int64

# now the way back works
julia> JSON3.read("1", Millisecond)
1 millisecond

# but...
julia> JSON3.write(Millisecond(1))
ERROR: MethodError: no method matching Int64(::Millisecond)
Closest candidates are:
  (::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number} at char.jl:50
  (::Type{T})(::BigInt) where T<:Union{Int128, Int16, Int32, Int64, Int8} at gmp.jl:356
  (::Type{T})(::Base.TwicePrecision) where T<:Number at twiceprecision.jl:243
  ...
Stacktrace:
 [1] construct(T::Type, args::Millisecond; kw::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})       
   @ StructTypes C:\Users\<user>\.julia\packages\StructTypes\NJXhA\src\StructTypes.jl:310
 [2] construct(T::Type, args::Millisecond)
   @ StructTypes C:\Users\<user>\.julia\packages\StructTypes\NJXhA\src\StructTypes.jl:310
 [3] write(::StructTypes.NumberType, buf::Vector{UInt8}, pos::Int64, len::Int64, x::Millisecond; kw::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ JSON3 C:\Users\<user>\.julia\packages\JSON3\VnoI3\src\write.jl:210
 [4] write(::StructTypes.NumberType, buf::Vector{UInt8}, pos::Int64, len::Int64, x::Millisecond)
   @ JSON3 C:\Users\<user>\.julia\packages\JSON3\VnoI3\src\write.jl:210
 [5] write(obj::Millisecond; kw::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ JSON3 C:\Users\<user>\.julia\packages\JSON3\VnoI3\src\write.jl:39
 [6] write(obj::Millisecond)
   @ JSON3 C:\Users\<user>\.julia\packages\JSON3\VnoI3\src\write.jl:37
 [7] top-level scope
   @ REPL[14]:1

Do I have to define:

Int(x::Millisecond) = x.value

and use the second variant?