spin_serde/
version.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4/// FixedVersion represents a version integer field with a const value.
5#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
6#[serde(into = "usize", try_from = "usize")]
7#[schemars(with = "usize", range = (min = V, max = V))]
8pub struct FixedVersion<const V: usize>;
9
10impl<const V: usize> From<FixedVersion<V>> for usize {
11    fn from(_: FixedVersion<V>) -> usize {
12        V
13    }
14}
15
16impl<const V: usize> TryFrom<usize> for FixedVersion<V> {
17    type Error = String;
18
19    fn try_from(value: usize) -> Result<Self, Self::Error> {
20        if value != V {
21            return Err(format!("invalid version {} != {}", value, V));
22        }
23        Ok(Self)
24    }
25}
26
27/// FixedVersion represents a version integer field with a const value,
28/// but accepts lower versions during deserialisation.
29#[derive(Clone, Debug, Default, Deserialize, JsonSchema)]
30#[serde(into = "usize", try_from = "usize")]
31#[schemars(with = "usize", range = (min = 1, max = V))]
32pub struct FixedVersionBackwardCompatible<const V: usize>;
33
34impl<const V: usize> From<FixedVersionBackwardCompatible<V>> for usize {
35    fn from(_: FixedVersionBackwardCompatible<V>) -> usize {
36        V
37    }
38}
39
40impl<const V: usize> TryFrom<usize> for FixedVersionBackwardCompatible<V> {
41    type Error = String;
42
43    fn try_from(value: usize) -> Result<Self, Self::Error> {
44        if value > V {
45            return Err(format!("invalid version {} > {}", value, V));
46        }
47        Ok(Self)
48    }
49}
50
51/// FixedStringVersion represents a version string field with a const value.
52#[derive(Clone, Debug, Default, Deserialize)]
53#[serde(into = "String", try_from = "String")]
54pub struct FixedStringVersion<const V: usize>;
55
56impl<const V: usize> From<FixedStringVersion<V>> for String {
57    fn from(_: FixedStringVersion<V>) -> String {
58        V.to_string()
59    }
60}
61
62impl<const V: usize> TryFrom<String> for FixedStringVersion<V> {
63    type Error = String;
64
65    fn try_from(value: String) -> Result<Self, Self::Error> {
66        if value.parse() != Ok(V) {
67            return Err(format!("invalid version {value:?} != \"{V}\""));
68        }
69        Ok(Self)
70    }
71}