Skip to content

Instantly share code, notes, and snippets.

@falrnd
Last active July 19, 2023 03:10
Show Gist options
  • Save falrnd/bbc5a53a72d519b2bcb8188dffc79b74 to your computer and use it in GitHub Desktop.
Save falrnd/bbc5a53a72d519b2bcb8188dffc79b74 to your computer and use it in GitHub Desktop.
techblog serde flatten + with&remote + rename
use std::ops::{Range, RangeInclusive};
use serde::{Deserialize, Serialize};
// シンプルな(de)serialize
#[derive(Serialize, Deserialize, Debug)]
struct SampleSimple {
xx_start: i32,
xx_end: i32,
}
// rename
#[derive(Serialize, Deserialize, Debug)]
struct SampleRename {
#[serde(rename = "xx_start")]
start: i32,
#[serde(rename = "xx_end")]
end: i32,
}
// flatten
#[derive(Serialize, Deserialize, Debug)]
struct SampleFlatten<T> {
#[serde(flatten)]
value_flatten: T,
}
#[derive(Serialize, Deserialize, Debug)]
struct SampleNewtype<T>(T);
// 本題の解決
#[derive(Serialize, Deserialize, Debug)]
#[serde(remote = "Range<i32>")]
struct RemoteRange {
#[serde(rename = "xx_start")]
start: i32,
#[serde(rename = "xx_end")]
end: i32,
}
////////
#[derive(Serialize, Deserialize, Debug)]
#[serde(remote = "RangeInclusive<i32>")]
struct RemoteRangeInclusive {
#[serde(rename = "xx_start", getter = "RangeInclusive::start")]
start: i32,
#[serde(rename = "xx_end", getter = "RangeInclusive::end")]
end: i32,
}
impl From<RemoteRangeInclusive> for RangeInclusive<i32> {
fn from(value: RemoteRangeInclusive) -> Self {
value.start..=value.end
}
}
////////
#[derive(Serialize, Deserialize, Debug)]
struct SampleNewTypeRemote(#[serde(with = "RemoteRange")] Range<i32>);
#[derive(Serialize, Deserialize, Debug)]
struct SampleFlattenRemote {
#[serde(flatten, with = "RemoteRangeInclusive")]
range_inclusive: RangeInclusive<i32>,
}
////////////////////////////////
fn main() {
let sample_json = r#"{"xx_start":3,"xx_end":5}"#;
sample_check::<SampleSimple>(sample_json);
sample_check::<SampleRename>(sample_json);
sample_check::<SampleNewtype<SampleSimple>>(sample_json);
sample_check::<SampleNewtype<SampleRename>>(sample_json);
sample_check::<SampleFlatten<SampleSimple>>(sample_json);
sample_check::<SampleFlatten<SampleRename>>(sample_json);
println!("本題↓");
sample_check::<SampleNewTypeRemote>(sample_json);
sample_check::<SampleFlattenRemote>(sample_json);
}
fn sample_check<'de, T: Serialize + Deserialize<'de> + std::fmt::Debug>(sample_json: &'de str) {
//deserialize
let de: T = serde_json::from_str(sample_json).unwrap();
println!("{de:?}");
//serialize
let ser = serde_json::to_string(&de).unwrap();
assert_eq!(sample_json, ser)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment