miniscript/primitives/
relative_locktime.rs1use core::{cmp, convert, fmt};
6
7use bitcoin::{relative, Sequence};
8
9#[derive(Debug, PartialEq)]
11pub struct RelLockTimeError {
12 value: u32,
13}
14
15impl fmt::Display for RelLockTimeError {
16 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
17 if self.value == 0 {
18 f.write_str("relative locktimes in Miniscript have a minimum value of 1")
19 } else {
20 debug_assert!(Sequence::from_consensus(self.value)
21 .to_relative_lock_time()
22 .is_none());
23 write!(f, "locktime value {} is not a valid BIP68 relative locktime", self.value)
24 }
25 }
26}
27
28#[cfg(feature = "std")]
29impl std::error::Error for RelLockTimeError {
30 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
31}
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
35pub struct RelLockTime(Sequence);
36
37impl RelLockTime {
38 pub const ZERO: Self = RelLockTime(Sequence::ZERO);
40
41 pub fn from_consensus(n: u32) -> Result<Self, RelLockTimeError> {
43 convert::TryFrom::try_from(Sequence::from_consensus(n))
44 }
45
46 pub fn to_consensus_u32(self) -> u32 { self.0.to_consensus_u32() }
49
50 pub fn from_height(height: u16) -> Self { RelLockTime(Sequence::from_height(height)) }
52
53 pub fn from_512_second_intervals(time: u16) -> Self {
55 RelLockTime(Sequence::from_512_second_intervals(time))
56 }
57
58 pub fn is_height_locked(&self) -> bool { self.0.is_height_locked() }
60
61 pub fn is_time_locked(&self) -> bool { self.0.is_time_locked() }
63}
64
65impl convert::TryFrom<Sequence> for RelLockTime {
66 type Error = RelLockTimeError;
67 fn try_from(seq: Sequence) -> Result<Self, RelLockTimeError> {
68 if seq.is_relative_lock_time() && seq != Sequence::ZERO {
69 Ok(RelLockTime(seq))
70 } else {
71 Err(RelLockTimeError { value: seq.to_consensus_u32() })
72 }
73 }
74}
75
76impl From<RelLockTime> for Sequence {
77 fn from(lock_time: RelLockTime) -> Sequence { lock_time.0 }
78}
79
80impl From<RelLockTime> for relative::LockTime {
81 fn from(lock_time: RelLockTime) -> relative::LockTime {
82 lock_time.0.to_relative_lock_time().unwrap()
83 }
84}
85
86impl cmp::PartialOrd for RelLockTime {
87 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { Some(self.cmp(other)) }
88}
89
90impl cmp::Ord for RelLockTime {
91 fn cmp(&self, other: &Self) -> cmp::Ordering {
92 let this = self.0.to_consensus_u32();
93 let that = other.0.to_consensus_u32();
94 this.cmp(&that)
95 }
96}
97
98impl fmt::Display for RelLockTime {
99 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
100}