I have a struct
similar to
pub struct FooBarList {
items: Vec<FooBar>,
name: String
}
pub struct FooBar {
pub foo: i32,
pub bar: i32
}
I need to serialize this into a flattened format i.e. something like
{
"name": "foo",
"foo1": 0,
"bar1": 41,
"foo2": 43,
"bar2": 12,
...
}
I tried doing the following:
impl Serialize for FooBarList {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let item_count = self.items.len();
let mut struct_ser = serializer.serialize_struct("FooBarList", 1 + 2 * item_count)?;
for (i, item) in (&self.items).into_iter().enumerate() {
struct_ser.serialize_field(format!("foo{}", i + 1).as_str(), &item.foo)?;
struct_ser.serialize_field(format!("bar{}", i + 1).as_str(), &item.bar)?;
}
struct_ser.serialize_field("name", &self.name)?;
struct_ser.end()
}
}
This fails however, because struct_ser.serialize_field()
requires &'static str
as the first parameter, but the &str
produced by format!().as_str()
has a non-static lifetime. I don't see a way to create the strings statically, as length of the number of items is only known at runtime. Is there any way to circumvent that limitation?
You can serialize it as a map using serialize_map()
:
impl Serialize for FooBarList {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let item_count = self.items.len();
let mut struct_ser = serializer.serialize_map(Some(1 + 2 * item_count))?;
for (i, item) in (&self.items).into_iter().enumerate() {
struct_ser.serialize_entry(&format!("foo{}", i + 1), &item.foo)?;
struct_ser.serialize_entry(&format!("bar{}", i + 1), &item.bar)?;
}
struct_ser.serialize_entry("name", &self.name)?;
struct_ser.end()
}
}
You can't give a name to the struct in this way, though.