fxfs/serialized_types/
traits.rs1use crate::serialized_types::DEFAULT_MAX_SERIALIZED_RECORD_SIZE;
6use crate::serialized_types::types::LATEST_VERSION;
7use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
8use fprint::TypeFingerprint;
9use serde::{Deserialize, Serialize};
10
11#[derive(
15 Debug, Default, Copy, Clone, Eq, PartialEq, PartialOrd, Serialize, Deserialize, TypeFingerprint,
16)]
17pub struct Version {
18 pub major: u32,
21 pub minor: u8,
25}
26impl std::fmt::Display for Version {
27 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28 write!(f, "{}.{}", self.major, self.minor)
29 }
30}
31impl Version {
32 pub fn deserialize_from<R: ?Sized>(reader: &mut R) -> anyhow::Result<Self>
33 where
34 R: std::io::Read,
35 {
36 Ok(Version { major: reader.read_u24::<LittleEndian>()?, minor: reader.read_u8()? })
37 }
38 pub fn serialize_into<W>(&self, writer: &mut W) -> anyhow::Result<()>
39 where
40 W: std::io::Write,
41 {
42 writer.write_u24::<LittleEndian>(self.major)?;
43 writer.write_u8(self.minor)?;
44 Ok(())
45 }
46}
47
48pub trait Versioned: Serialize + for<'de> Deserialize<'de> {
54 fn max_serialized_size() -> Option<u64> {
58 Some(DEFAULT_MAX_SERIALIZED_RECORD_SIZE)
59 }
60
61 fn deserialize_from<R: ?Sized>(reader: &mut R, _version: Version) -> anyhow::Result<Self>
62 where
63 R: std::io::Read,
64 for<'de> Self: serde::Deserialize<'de>,
65 {
66 use bincode::Options;
67 let options = bincode::DefaultOptions::new().allow_trailing_bytes();
68 let result = if let Some(limit) = Self::max_serialized_size() {
69 options.with_limit(limit).deserialize_from(reader)
70 } else {
71 options.deserialize_from(reader)
72 };
73 result.map_err(map_bincode_error)
74 }
75 fn serialize_into<W>(&self, writer: &mut W) -> anyhow::Result<()>
76 where
77 W: std::io::Write,
78 Self: serde::Serialize,
79 {
80 use bincode::Options;
81 let options = bincode::DefaultOptions::new().allow_trailing_bytes();
82 let result = if let Some(limit) = Self::max_serialized_size() {
83 options.with_limit(limit).serialize_into(writer, self)
84 } else {
85 options.serialize_into(writer, self)
86 };
87 result.map_err(map_bincode_error)
88 }
89}
90
91pub trait VersionedLatest: Versioned + TypeFingerprint {
94 fn deserialize_from_version<R>(reader: &mut R, version: Version) -> anyhow::Result<Self>
96 where
97 R: std::io::Read,
98 Self: Sized;
99
100 fn deserialize_with_version<R>(reader: &mut R) -> anyhow::Result<(Self, Version)>
103 where
104 R: std::io::Read,
105 Self: Sized,
106 {
107 let version = Version::deserialize_from(reader)?;
108 Ok((Self::deserialize_from_version(reader, version)?, version))
109 }
110 fn serialize_with_version<W>(&self, writer: &mut W) -> anyhow::Result<()>
112 where
113 W: std::io::Write,
114 Self: Sized,
115 {
116 LATEST_VERSION.serialize_into(writer)?;
117 self.serialize_into(writer)
118 }
119}
120
121fn map_bincode_error(e: Box<bincode::ErrorKind>) -> anyhow::Error {
122 if let bincode::ErrorKind::Io(io) = *e { io.into() } else { e.into() }
124}