Skip to main content

psbt_v2/
version.rs

1// SPDX-License-Identifier: CC0-1.0
2
3use 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/// The PSBT version.
12#[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    /// The original PSBT format [BIP-174].
18    ///
19    /// [BIP-174]: <https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki>
20    pub const ZERO: Self = Self(0);
21
22    /// The second PSBT version [BIP-370].
23    ///
24    /// [BIP-370]: <https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki>
25    pub const TWO: Self = Self(2);
26}
27
28impl Version {
29    /// Returns the version number as a `u32`.
30    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/// Unsupported PSBT version.
62#[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}