Serde: How to implement multiple custom sequences?

368 Views Asked by At

So I'm writing a custom format to serialize/deserialize to/from a save game file format.

This question is me asking if my current approach is reasonable and what's the best way to solve this problem.

Since the design of the format is very questionable (despite being pretty widely used, paradox interactives save file format).

There are seemingly 3 forms of sequences.

In rising complexity we have:

Placeholder struct:

The formats are typically used with structs, so this will be the placeholder struct:

struct X { a:i64, b:String }

1:

some_param={
    213 8450 23 1234 -21349
}

And with structs:

some_parameter={
    {
        a=123
        b="abc"
    }
    {
        a=-2
        b="asd"
    }
    // ...
}

2:

some_parameter={
    0={
        a=3
        b="asdj"
    }
    1={
        a=-2
        b="fdgdd"
    }
    2={
        a=5
        b="uikpkcvd"
    }
    // ...
}

3:

some_parameter={
    a=123
    b="abc"
}
some_parameter={
    a=12343
    b="ajbc"
}
some_parameter={
    a=122343
    b="abfac"
}
// ...

When thise format is used with primitives it looks like:

some_parameter=123
some_parameter=14523
some_parameter=122443
// ...

(I have not seen 3 used with primitives, but I can make a good guess how they should work considering the others)

My attempt

My attempt right now is to define my own structs which each represent one of the seqeunce forms.

E.g.

Struct Seq1<T> { data: Vec<T> }
Struct Seq2<T> { data: Vec<T> }
Struct Seq3<T> { data: Vec<T> }

And then write custom impl<T> Serialize for each (based off the standard sequence one from here).

To handle indents I added an indent field to my definition of Serializer:

pub struct Serializer {
    output: String,
    indent: usize
}

My attempt for sequence form 2:

use serde::ser::{Serialize, SerializeSeq, SerializeMap};
use crate::ser::Serializer;

pub struct IDSeq<T> {
    data: Vec<T>
}
impl<T> Serialize for IDSeq<T>
where
    T: Serialize,
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::ser::Serializer,
    {
        let mut seq = serializer.serialize_seq(Some(self.data.len()))?;
        for (indx,e) in self.data.iter().enumerate() {
            serializer.output += "\t".repeat(serializer.indent) + format!("{}=",indx);
            seq.serialize_element(e)?;
        }
        seq.end()
    }
}

Currently this errors on serializer.outputs and serializer.indents with the errors:

no field `output` on type `S`

and

no field `indent` on type `S`

respectively.

Given the definition of Serializer:

pub struct Serializer {
    output: String,
    indent: usize
}

I think this is some issue to do with the trait serde::ser::Serializer vs the actual struct. I don't know how to fix this.

(ofc there is a bunch of additional code here I'm not showing, but I don't think it neccessary to illustrate the approach)

So I know this is quite a bit of an infomation dump, sorry for that.

0

There are 0 best solutions below