Reputation: 392
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?
Upvotes: 1
Views: 897
Reputation: 71430
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.
Upvotes: 2