serde serialization and deserialization support
ngerow2025 opened this issue · 5 comments
There is no way to currently encode chess positions from this crate in an efficient way with a binary encoding and serde support would enable this without much trouble. I am willing to implement this through a feature flag with all of the public facing types in the crate.
Hi. The reason why I've been hesitant to add this, is that there's no single best way to implement these traits. For example, for efficient IPC, I'd expect Square::A1
to be serialized as 0
. For a public facing JSON API, I'd find "a1"
more suitable.
Types do implement common traits like TryFrom
, Into
, FromStr
, and Display
. I find serde_with
useful to explicitly explicitly choose the format.
For example, serde_with::TryFromInto
for round trips via integers, serde_with::DisplayFromStr
for round trips via string representations.
Any tricks with which I can de/ser ArrayVec<T, CAP>
? I have something like this:
#[derive(Serialize, Deserialize)]
pub struct OrderedSan {
pub sans: ArrayVec<SanPlus, 128>,
}
arrayvec
has serde
support but I can't seem to make it integrate with DisplayFromStr
.
edit: the following works but not the most ergonomic
#[serde_as]
#[derive(Serialize, Deserialize)]
pub struct SanPlusWrapper {
#[serde_as(as = "DisplayFromStr")]
pub sp: SanPlus,
}
#[derive(Serialize, Deserialize)]
pub struct OrderedSan {
pub sans: ArrayVec<SanPlusWrapper, 128>,
}
More workarounds ... if allocating a Vec
is acceptable:
#[serde_as]
#[derive(Serialize)]
struct Example {
#[serde_as(as = "Vec<DisplayFromStr>")]
moves: Vec<SanPlus>,
}
Or borrowing to serialize:
#[serde_as]
#[derive(Serialize)]
struct Example<'a> {
#[serde_as(as = "&[DisplayFromStr]")]
moves: &'a [SanPlus],
}
I currently have the Vec implementation, was trying to move to arrayvec to see if I could get some perf gains :)
It's because arrayvec
does not implement SerialiseAs
and DeserialiseAs
. I implemented them: bluss/arrayvec@master...kraktus:arrayvec:serde_with
and will try to merge it upstream under the serde
or new serde_with
feature, but I expect the patch to be rejected. I'll then try to add it as a arrayvec07
feature to serde_with
where I've more hope it'll be accepted.
Side note. The SerialiseAs
/DeserialiseAs
is a type hell and I didn't really understand how it worked but tests pass so should be good.
Working version with the patch. For a binary, using a git dep is fine.
// in Cargo.toml
// arrayvec = { git = "https://github.com/kraktus/arrayvec", branch = "serde_with", features = ["serde"] }
#[serde_as]
#[derive(Serialize, Deserialize)]
pub struct Native {
#[serde_as(as = "ArrayVec<DisplayFromStr,128>")]
pub sans: ArrayVec<SanPlus, 128>,
}