Skip to main content

format_description

Macro format_description 

Source
format_description!() { /* proc-macro */ }
Available on crate feature macros and crate feature serde and (crate features formatting or parsing) only.
Expand description

Generate a custom serializer and deserializer from a format string or an existing format.

The format description syntax accepted by this macro is the same as format_description::parse(), which can be found in the book.

§Syntax

It is recommended to use version 3. For backwards compatibility, this macro defaults to version 1. To use version 2 or version 3, you can specify the version as the first argument: serde::format_description!(version = 2, mod_name, Date, FORMAT).

For versions 1 and 2, this macro is invoked as serde::format_description!(mod_name, Date, FORMAT) where FORMAT is either a "<format string>" or something that implements Formattable and Parsable. This puts a module named mod_name in the current scope that can be used to format Date structs. A submodule (mod_name::option) is also generated for Option<Date>. Both modules are only visible in the current scope by default. To increase visibility, you can specify pub, pub(crate), or similar before the module name: serde::format_description!(pub mod_name, Date, FORMAT).

For version 3, this macro is invoked as serde::format_description!(mod mod_name [Date] = FORMAT). As with versions 1 and 2, visibility can be specified before the mod keyword. The type being formatted and/or parsed must be in scope, as the macro will not import it for you. Note: the mod keyword indicates that this is version 3 of the macro; specifying version = 3 is accepted but unnecessary.

§Semantics

The returned Option will contain a deserialized value if present and None if the field is present but the value is null (or the equivalent in other formats). To return None when the field is not present, you should use #[serde(default)] on the field.

Note: Due to serde-rs/serde#2878, you will need to apply #[serde(default)] if you want a missing field to deserialize as None.

§Examples

Using a format string:

use ::serde::{Serialize, Deserialize};
use time::serde;

// Makes a module `mod my_format { ... }`.
serde::format_description!(my_format, OffsetDateTime, "hour=[hour], minute=[minute]");

#[derive(Serialize, Deserialize)]
struct SerializesWithCustom {
    #[serde(with = "my_format")]
    dt: OffsetDateTime,
    #[serde(with = "my_format::option", default)]
    maybe_dt: Option<OffsetDateTime>,
}

Define the format separately to be used in multiple places:

use ::serde::{Serialize, Deserialize};
use time::serde;
use time::format_description::StaticFormatDescription;

const DATE_TIME_FORMAT: StaticFormatDescription = time::macros::format_description!(
    "hour=[hour], minute=[minute]"
);

// Makes a module `mod my_format { ... }`.
serde::format_description!(my_format, OffsetDateTime, DATE_TIME_FORMAT);

#[derive(Serialize, Deserialize)]
struct SerializesWithCustom {
    #[serde(with = "my_format")]
    dt: OffsetDateTime,
    #[serde(with = "my_format::option", default)]
    maybe_dt: Option<OffsetDateTime>,
}

fn main() {
    let str_ts = OffsetDateTime::now_utc().format(DATE_TIME_FORMAT).unwrap();
}

Customize the configuration of ISO 8601 formatting/parsing:

use ::serde::{Serialize, Deserialize};
use time::serde;
use time::format_description::well_known::{iso8601, Iso8601};

const CONFIG: iso8601::EncodedConfig = iso8601::Config::DEFAULT
    .set_year_is_six_digits(false)
    .encode();
const FORMAT: Iso8601<CONFIG> = Iso8601::<CONFIG>;

// Makes a module `mod my_format { ... }`.
serde::format_description!(my_format, OffsetDateTime, FORMAT);

#[derive(Serialize, Deserialize)]
struct SerializesWithCustom {
    #[serde(with = "my_format")]
    dt: OffsetDateTime,
    #[serde(with = "my_format::option", default)]
    maybe_dt: Option<OffsetDateTime>,
}