scarb_metadata/
version_pin.rs1use std::fmt;
2
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4
5#[cfg(doc)]
6use super::Metadata;
7
8const METADATA_VERSION: u64 = {
9 let mut bytes = env!("CARGO_PKG_VERSION_MAJOR").as_bytes();
11 let mut num = 0u64;
12 while let [ch @ b'0'..=b'9', rem @ ..] = bytes {
13 bytes = rem;
14 num *= 10;
15 num += (*ch - b'0') as u64;
16 }
17 num
18};
19
20#[derive(Copy, Clone, Default, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
25pub struct VersionPin;
26
27impl VersionPin {
28 pub const fn numeric(self) -> u64 {
30 METADATA_VERSION
31 }
32
33 pub const fn from_numeric(num: u64) -> Option<Self> {
35 if num == Self.numeric() {
36 Some(Self)
37 } else {
38 None
39 }
40 }
41}
42
43impl Serialize for VersionPin {
44 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
45 s.serialize_u64(self.numeric())
46 }
47}
48
49impl<'de> Deserialize<'de> for VersionPin {
50 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<VersionPin, D::Error> {
51 use serde::de::Error;
52 let num = u64::deserialize(d)?;
53 VersionPin::from_numeric(num)
54 .ok_or_else(|| Error::custom(format!("expected metadata version {}", Self.numeric())))
55 }
56}
57
58impl From<VersionPin> for u64 {
59 fn from(pin: VersionPin) -> Self {
60 pin.numeric()
61 }
62}
63
64impl fmt::Display for VersionPin {
65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66 write!(f, "{}", Self.numeric())
67 }
68}