lenient_derive

Crates.iolenient_derive
lib.rslenient_derive
version0.1.2
created_at2025-06-04 20:22:59.682091+00
updated_at2025-06-05 18:29:22.875757+00
descriptionA procedural macro to derive fault-tolerant Serde deserialization using #[lenient] and #[optional] annotations.
homepage
repositoryhttps://github.com/masumeebhami/lenient
max_upload_size
id1700849
size7,414
(masumeebhami)

documentation

README

๐Ÿ› ๏ธ lenient_derive

This crate provides the #[derive(LenientDeserialize)] procedural macro to enable fault-tolerant Serde deserialization for struct fields in Rust.

It is designed to work in conjunction with the lenient crate, which defines wrappers for lenient field handling using serde.


โœจ Features

  • #[derive(LenientDeserialize)] for struct-level deserialization
  • Field-level #[lenient] to fallback to default on deserialization failure
  • Field-level #[optional] to fallback to None on failure
  • Designed for use with Lenient<T> and Optional<T> wrappers
  • Automatically implements Deserialize for the annotated struct

๐Ÿ“ฆ Example Usage

In your Cargo.toml:

[dependencies]
lenient = "0.1"

In your Rust code:

use lenient_derive::LenientDeserialize;
use serde::Deserialize;

#[derive(Debug, Default)]
struct Age(pub u32);
impl<'de> Deserialize<'de> for Age {
    fn deserialize<D>(de: D) -> Result<Self, D::Error>
    where D: serde::Deserializer<'de> {
        Ok(Age(u32::deserialize(de)?))
    }
}

#[derive(Debug, Default)]
struct Score(pub u8);
impl<'de> Deserialize<'de> for Score {
    fn deserialize<D>(de: D) -> Result<Self, D::Error>
    where D: serde::Deserializer<'de> {
        Ok(Score(u8::deserialize(de)?))
    }
}

#[derive(Debug, Default, LenientDeserialize)]
struct UserProfile {
    #[lenient]
    age: Age,
    #[optional]
    score: Score,
    #[lenient]
    nickname: String,
}

๐Ÿงช How It Works

The macro generates an internal deserialization wrapper struct like:

#[derive(Deserialize)]
struct UserProfileInternal {
    #[serde(default)]
    age: Lenient<Age>,
    #[serde(default)]
    score: Optional<Score>,
    #[serde(default)]
    nickname: Lenient<String>,
}

Then it provides a Deserialize implementation for the outer struct using the inner one.


๐Ÿ“„ License

MIT

Commit count: 0

cargo fmt