1use core::convert::TryFrom;
4use core::fmt;
5
6use bitcoin::consensus::encode as consensus;
7
8use crate::prelude::Vec;
9use crate::serialize::{self, Deserialize, Serialize};
10
11#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
13#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
14pub struct Version(u32);
15
16impl Version {
17 pub const ZERO: Self = Self(0);
21
22 pub const TWO: Self = Self(2);
26}
27
28impl Version {
29 pub fn to_u32(self) -> u32 { self.0 }
31}
32
33impl From<Version> for u32 {
34 fn from(v: Version) -> u32 { v.to_u32() }
35}
36
37impl TryFrom<u32> for Version {
38 type Error = UnsupportedVersionError;
39
40 fn try_from(n: u32) -> Result<Self, Self::Error> {
41 match n {
42 0 => Ok(Version::ZERO),
43 2 => Ok(Version::TWO),
44 n => Err(UnsupportedVersionError(n)),
45 }
46 }
47}
48
49impl Serialize for Version {
50 fn serialize(&self) -> Vec<u8> { consensus::serialize(&self.to_u32()) }
51}
52
53impl Deserialize for Version {
54 fn deserialize(bytes: &[u8]) -> Result<Self, serialize::Error> {
55 let n: u32 = consensus::deserialize(bytes)?;
56 let version = Version::try_from(n)?;
57 Ok(version)
58 }
59}
60
61#[derive(Debug, Clone, PartialEq, Eq)]
63#[non_exhaustive]
64pub struct UnsupportedVersionError(u32);
65
66impl fmt::Display for UnsupportedVersionError {
67 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68 write!(f, "unsupported version, we only support v0 and v2: {}", self.0)
69 }
70}
71
72#[cfg(feature = "std")]
73impl std::error::Error for UnsupportedVersionError {
74 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
75}