serde_more 0.1.3

Procedural macro to add arbitrary data when serializing using serde
Documentation
use rstest::rstest;
use serde::Serialize;
use serde_json::json;
use serde_more::SerializeMore;
use serde_with::serde_as;
use testresult::TestResult;

#[derive(SerializeMore)]
#[more(key = "normal_field_squared", value = "squared")]
struct Basic {
    normal_field: u32,
}

impl Basic {
    fn squared(&self) -> u32 {
        self.normal_field.pow(2)
    }
}

#[derive(SerializeMore)]
#[more(key = "x_1", value = "plus_one")]
#[more(key = "x_2", value = "plus_two")]
struct Multi {
    x: u8,
}

impl Multi {
    fn plus_one(&self) -> u8 {
        self.x + 1
    }
    fn plus_two(&self) -> u8 {
        self.x + 2
    }
}

#[derive(SerializeMore)]
#[serde(rename_all = "kebab-case")]
#[more(k = "extraVal", v = "extra_val")]
struct WithSerdeAttrs {
    field_name: u32,
    #[serde(skip_serializing_if = "Option::is_none")]
    opt_value: Option<u8>,
}

impl WithSerdeAttrs {
    fn extra_val(&self) -> &'static str {
        "ok"
    }
}

#[serde_as]
#[derive(SerializeMore)]
#[more(k = "payload_len")]
struct WithSerdeAsAttrs {
    #[serde_as(as = "serde_with::hex::Hex")]
    payload: Vec<u8>,
}

impl WithSerdeAsAttrs {
    fn payload_len(&self) -> usize {
        self.payload.len()
    }
}

#[derive(SerializeMore)]
#[more(k = "a", position = "front")]
#[more(k = "d")]
#[more(k = "e", position = "back")]
#[more(k = "b", position = "front")]
struct WithPosition {
    c: &'static str,
}

impl WithPosition {
    const fn a(&self) -> &str {
        "a"
    }

    const fn d(&self) -> &str {
        "d"
    }

    const fn e(&self) -> &str {
        "e"
    }

    const fn b(&self) -> &str {
        "b"
    }
}

#[rstest]
#[case::struct_single(&Basic { normal_field: 7 }, json!({"normal_field":7, "normal_field_squared":49}))]
#[case::struct_multiple(&Multi { x: 3 }, json!({"x":3,"x_1":4,"x_2":5}))]
#[case::serde_attrs(&WithSerdeAttrs { field_name: 1, opt_value: None }, json!({"field-name":1, "extraVal":"ok"}))]
#[case::serde_with(&WithSerdeAsAttrs { payload: vec![0x0a, 0xff] }, json!({"payload":"0aff","payload_len":2}))]
#[case::with_position(&WithPosition { c: "c" }, json!({"a":"a","b":"b","c":"c","d":"d","e":"e"}))]
fn serialize_more<T: Serialize>(
    #[case] input: T,
    #[case] expected: serde_json::Value,
) -> TestResult {
    let v = serde_json::to_value(input)?;
    assert_eq!(v, expected);
    Ok(())
}