|
1 | | -# De/Deser |
| 1 | +# De/De |
| 2 | + |
| 3 | +abstract type DeserError <: Exception end |
| 4 | + |
| 5 | +struct ParamError <: DeserError |
| 6 | + key::Any |
| 7 | +end |
| 8 | + |
| 9 | +function Base.show(io::IO, e::ParamError) |
| 10 | + return print( |
| 11 | + io, |
| 12 | + "ParamError: parameter '$(e.key)' was not passed or has the value 'nothing'", |
| 13 | + ) |
| 14 | +end |
| 15 | + |
| 16 | +struct TagError <: DeserError |
| 17 | + tag::Any |
| 18 | +end |
| 19 | + |
| 20 | +function Base.show(io::IO, e::TagError) |
| 21 | + return print(io, "TagError: tag for method '$(e.tag)' is not declared") |
| 22 | +end |
| 23 | + |
| 24 | +struct WrongType <: DeserError |
| 25 | + maintype::DataType |
| 26 | + key::Any |
| 27 | + value::Any |
| 28 | + from_type::Any |
| 29 | + to_type::Any |
| 30 | +end |
| 31 | + |
| 32 | +function Base.show(io::IO, e::WrongType) |
| 33 | + return print( |
| 34 | + io, |
| 35 | + "WrongType: for '$(e.maintype)' value '$(e.value)' has wrong type '$(e.key)::$(e.from_type)', must be '$(e.key)::$(e.to_type)'", |
| 36 | + ) |
| 37 | +end |
2 | 38 |
|
3 | 39 | """ |
4 | 40 | ClassType |
@@ -543,3 +579,54 @@ function deser(::CustomType, ::Type{D}, data::N)::D where {D<:Any,N<:NamedTuple} |
543 | 579 |
|
544 | 580 | return D(vals...) |
545 | 581 | end |
| 582 | + |
| 583 | +function tag(::Type{T}, ::Val{x}) where {T,x} |
| 584 | + return throw(TagError(x)) |
| 585 | +end |
| 586 | + |
| 587 | +tag(::Type{T}, ::Nothing) where {T} = T |
| 588 | + |
| 589 | +(tag_key(::Type)::Nothing) = nothing |
| 590 | +(tag_val(::Type{T}, ::Nothing, v)::Nothing) where {T} = nothing |
| 591 | + |
| 592 | +function tag_val(::Type{T}, k, v) where {T} |
| 593 | + try |
| 594 | + Val(Symbol(v[k])) |
| 595 | + catch |
| 596 | + throw(ParamError(k)) |
| 597 | + end |
| 598 | +end |
| 599 | + |
| 600 | +deser_type(::Type{T}, x) where {T} = tag(T, tag_val(T, tag_key(T), x)) |
| 601 | +deser_value(::Type{T}, x) where {T} = x |
| 602 | + |
| 603 | +""" |
| 604 | + Serde.to_deser(::Type{T}, x) -> T |
| 605 | +
|
| 606 | +Creates a new object of type `T` with values corresponding to the key-value pairs of the dictionary `x`. |
| 607 | +
|
| 608 | +## Examples |
| 609 | +```julia-repl |
| 610 | +julia> struct Info |
| 611 | + id::Int64 |
| 612 | + salary::Int64 |
| 613 | + end |
| 614 | +
|
| 615 | +julia> struct Person |
| 616 | + name::String |
| 617 | + age::Int64 |
| 618 | + info::Info |
| 619 | + end |
| 620 | +
|
| 621 | +julia> info_data = Dict("id" => 12, "salary" => 2500); |
| 622 | +
|
| 623 | +julia> person_data = Dict("name" => "Michael", "age" => 25, "info" => info_data); |
| 624 | +
|
| 625 | +julia> Serde.to_deser(Person, person_data) |
| 626 | +Person("Michael", 25, Info(12, 2500)) |
| 627 | +``` |
| 628 | +""" |
| 629 | +to_deser(::Type{T}, x) where {T} = deser(deser_type(T, x), deser_value(T, x)) |
| 630 | + |
| 631 | +to_deser(::Type{Nothing}, x) = nothing |
| 632 | +to_deser(::Type{Missing}, x) = missing |
0 commit comments