1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4#[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#[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#[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}