Crates.io | merde_json_types |
lib.rs | merde_json_types |
version | 2.2.3 |
source | src |
created_at | 2024-07-31 16:31:36.58067 |
updated_at | 2024-09-05 12:03:01.819187 |
description | Wrapper types for merde_json that implement serialization/deserialization |
homepage | |
repository | https://github.com/bearcove/merde_json |
max_upload_size | |
id | 1321091 |
size | 12,151 |
Logo by MisiasArt
merde_json_types
is a companion crate to merde_json,
providing wrapper types that solve two problems at once.
merde_json
traitsI'm thinking about the time crate, the chrono crate, camino, etc.
If you have, say, a time::OffsetDateTime
in one of your structs,
then merde_json's derive macro will not work. You are going to need
a wrapper of some sort, and that's the kind of type this crate provides.
If you enable the time-serialize
, time-deserialize
, and merde_json
features, you can do this:
use merde_json::{from_str, JsonSerialize, ToRustValue};
use merde_json_types::time::Rfc3339;
let dt = Rfc3339(time::OffsetDateTime::now_utc());
let serialized = dt.to_json_string();
let deserialized: Rfc3339<time::OffsetDateTime> =
merde_json::from_str(&serialized).unwrap().to_rust_value().unwrap();
assert_eq!(dt, deserialized);
merde_json
optionalThe [time::Rfc3339] type is exported by this crate as soon as the time-types
feature is enabled. But merde_json_types
doesn't even depend on merde_json
(or provide serialization/deserialization implementations) unless you activate
its merde_json
feature!
That means, you can have your crate unconditionally depend on merde_json_types
,
and use Rfc3339
in your public structs:
use merde_json::{Fantome, JsonSerialize, ToRustValue};
use merde_json_types::time::Rfc3339;
#[derive(Debug, PartialEq, Eq)]
pub struct Person<'src, 'val> {
pub name: String,
pub birth_date: Rfc3339<time::OffsetDateTime>,
pub _boo: Fantome<'src, 'val>,
}
merde_json::derive! {
impl (JsonSerialize, JsonDeserialize) for Person { name, birth_date }
}
And still only depend on merde_json
when your own feature gets activated:
[dependencies]
merde_json_types = "2"
merde_json = { version = "2", optional = true }
[features]
merde_json = ["dep:merde_json", "merde_json_types/merde_json"]
Of course, for that to work, we need to get rid of any unconditional mention of
merde_json
in our code, which would become something like:
use std::marker::PhantomData;
use merde_json_types::time::Rfc3339;
#[derive(Debug, PartialEq, Eq)]
pub struct Person<'src, 'val> {
pub name: String,
pub birth_date: Rfc3339<time::OffsetDateTime>,
/// This field still _has_ to be named `_boo`, but we can't use
/// the `Fantome` type here without pulling in `merde_json`: so,
/// we use `PhantomData` instead.
pub _boo: PhantomData<(&'src (), &'val ())>,
}
#[cfg(feature = "merde_json")]
merde_json::derive! {
impl (JsonSerialize, JsonDeserialize) for Person { name, birth_date }
}