Serde.jl

Serde is a Julia library for (de)serializing data to/from various formats. Inspired by serde.rs, it provides a strategy-based API for customizing serialization behaviour without boilerplate. Supported formats:

Format
JSON
TOML
XML
YAML
CSV
Query
MsgPack
BSON
Deserialization
Serialization

Installation

] add Serde

Usage

Deserialization

using Dates, Serde

struct JuliaCon
    title::String
    start_date::Date
    end_date::Date
end

function Serde.deser(::Type{JuliaCon}, ::Type{Date}, v::String)
    return Dates.Date(v, "U d, yyyy")
end

json = """{"title":"JuliaCon 2024","start_date":"July 9, 2024","end_date":"July 13, 2024"}"""

julia> from_json(JuliaCon, json)
JuliaCon("JuliaCon 2024", Date("2024-07-09"), Date("2024-07-13"))

The same struct works across all formats:

toml = """
title = "JuliaCon 2024"
start_date = "July 9, 2024"
end_date = "July 13, 2024"
"""

julia> from_toml(JuliaCon, toml)
JuliaCon("JuliaCon 2024", Date("2024-07-09"), Date("2024-07-13"))

query = "title=JuliaCon 2024&start_date=July 9, 2024&end_date=July 13, 2024"

julia> from_query(JuliaCon, query)
JuliaCon("JuliaCon 2024", Date("2024-07-09"), Date("2024-07-13"))

csv = """
title,start_date,end_date
"JuliaCon 2024","July 9, 2024","July 13, 2024"
"""

julia> from_csv(JuliaCon, csv)
1-element Vector{JuliaCon}:
 JuliaCon("JuliaCon 2024", Date("2024-07-09"), Date("2024-07-13"))

If you want to see more deserialization options, take a look at the corresponding section of the documentation.

Serialization

using Dates, Serde

struct JuliaCon
    title::String
    start_date::Date
    end_date::Date
end

Serde.ser_type(::Type{JuliaCon}, v::Date) = Dates.format(v, "U d, yyyy")

juliacon = JuliaCon("JuliaCon 2024", Date(2024, 7, 9), Date(2024, 7, 13))

julia> to_json(juliacon) |> print
{"title":"JuliaCon 2024","start_date":"July 9, 2024","end_date":"July 13, 2024"}

julia> to_toml(juliacon) |> print
title = "JuliaCon 2024"
start_date = "July 9, 2024"
end_date = "July 13, 2024"

If you want to see more serialization options, take a look at the corresponding section of the documentation.

Strategies

Strategies rename fields globally without touching the struct definition:

struct Order
    order_id::Int
    total_amount::Float64
end

julia> to_json(CamelCase(), Order(1, 99.9))
"{\"orderId\":1,\"totalAmount\":99.9}"

julia> from_json(CamelCase(), Order, "{\"orderId\":1,\"totalAmount\":99.9}")
Order(1, 99.9)

Combine multiple strategies with With:

struct MyCtx end

Serde.has_default(::MyCtx, ::Type{Order}, ::Val{:total_amount}) = true
Serde.deser_default(::MyCtx, ::Type{Order}, ::Val{:total_amount}) = 0.0

julia> from_json(With(CamelCase(), MyCtx()), Order, "{\"orderId\":5}")
Order(5, 0.0)