-
Hi, I'm somewhat new to the Rust language and having a rough time with As shown in example below I have a struct Using With some hackery I was able to get use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_with::{serde_as, DeserializeAs, SerializeAs};
use std::collections::BTreeMap;
mod external {
#[derive(Debug, Clone)]
pub struct A {
pub x: String,
}
}
use external::A;
#[serde(remote = "A")]
#[derive(Debug, Clone, Serialize, Deserialize)]
struct ADef {
pub x: String,
}
#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Foo {
#[serde(with = "ADef")]
pub inst: A,
#[serde_as(as = "Option<ADef>")]
pub opt: Option<A>,
// Can't get this working at all
// #[serde_as(as = "BTreeMap<String, ADef>")]
// pub map: BTreeMap<String, A>,
// Confusingly enough defining identity transform like this doesn't compile either
// #[serde_as(as = "BTreeMap<String, String>")]
// pub map2: BTreeMap<String, String>,
}
// Required for `as = "Option<ADef>"` to work :(
impl SerializeAs<A> for ADef {
fn serialize_as<S>(source: &A, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
#[derive(Serialize)]
struct Helper<'a>(#[serde(with = "ADef")] &'a A);
Helper(source).serialize(serializer)
}
}
impl<'de> DeserializeAs<'de, A> for ADef {
fn deserialize_as<D>(deserializer: D) -> Result<A, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct Helper(#[serde(with = "ADef")] A);
let helper = Helper::deserialize(deserializer)?;
let Helper(v) = helper;
Ok(v)
}
}
fn main() {
let mut map = BTreeMap::new();
map.insert("a".to_owned(), A { x: "a".to_owned() });
map.insert("b".to_owned(), A { x: "b".to_owned() });
let s = serde_yaml::to_string(&Foo {
inst: A {
x: "inst".to_owned(),
},
opt: Some(A {
x: "opt".to_owned(),
}),
// map: map,
})
.unwrap();
println!("{}", s);
} |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
Hi, you are quite close. The correct annotation on As you noticed identity transforms do not work. A blanked implementation is not possible as it would overlap with other implementations. Instead you need to use |
Beta Was this translation helpful? Give feedback.
-
Thanks @jonasbb, that solved my problem. Thank you for maintaining this crate 👍 |
Beta Was this translation helpful? Give feedback.
Hi, you are quite close. The correct annotation on
map
is#[serde_as(as = "BTreeMap<_, ADef>")]
.As you noticed identity transforms do not work. A blanked implementation is not possible as it would overlap with other implementations. Instead you need to use
_
orSame
.