bitcoin_units/locktime/
relative.rs1use core::fmt;
6
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
12#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
13pub struct Height(u16);
14
15impl Height {
16 pub const ZERO: Self = Height(0);
18
19 pub const MIN: Self = Self::ZERO;
21
22 pub const MAX: Self = Height(u16::max_value());
24
25 #[inline]
27 pub const fn from_height(blocks: u16) -> Self { Height(blocks) }
28
29 #[inline]
31 pub fn value(self) -> u16 { self.0 }
32
33 #[inline]
36 pub fn to_consensus_u32(&self) -> u32 { self.0.into() }
37}
38
39impl From<u16> for Height {
40 #[inline]
41 fn from(value: u16) -> Self { Height(value) }
42}
43
44crate::impl_parse_str_from_int_infallible!(Height, u16, from);
45
46impl fmt::Display for Height {
47 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
48}
49
50#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
54#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
55pub struct Time(u16);
56
57impl Time {
58 pub const ZERO: Self = Time(0);
60
61 pub const MIN: Self = Time::ZERO;
63
64 pub const MAX: Self = Time(u16::max_value());
66
67 #[inline]
71 pub const fn from_512_second_intervals(intervals: u16) -> Self { Time(intervals) }
72
73 #[inline]
80 #[rustfmt::skip] pub const fn from_seconds_floor(seconds: u32) -> Result<Self, TimeOverflowError> {
82 let interval = seconds / 512;
83 if interval <= u16::MAX as u32 { Ok(Time::from_512_second_intervals(interval as u16)) } else {
86 Err(TimeOverflowError { seconds })
87 }
88 }
89
90 #[inline]
97 #[rustfmt::skip] pub const fn from_seconds_ceil(seconds: u32) -> Result<Self, TimeOverflowError> {
99 let interval = (seconds + 511) / 512;
100 if interval <= u16::MAX as u32 { Ok(Time::from_512_second_intervals(interval as u16)) } else {
103 Err(TimeOverflowError { seconds })
104 }
105 }
106
107 #[inline]
109 pub fn value(self) -> u16 { self.0 }
110
111 #[inline]
114 pub fn to_consensus_u32(&self) -> u32 { (1u32 << 22) | u32::from(self.0) }
115}
116
117crate::impl_parse_str_from_int_infallible!(Time, u16, from_512_second_intervals);
118
119impl fmt::Display for Time {
120 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
121}
122
123#[derive(Debug, Clone, PartialEq, Eq)]
125pub struct TimeOverflowError {
126 pub(crate) seconds: u32,
129}
130
131impl TimeOverflowError {
132 pub fn new(seconds: u32) -> Self {
138 assert!(u16::try_from((seconds + 511) / 512).is_err());
139 Self { seconds }
140 }
141}
142
143impl fmt::Display for TimeOverflowError {
144 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
145 write!(
146 f,
147 "{} seconds is too large to be encoded to a 16 bit 512 second interval",
148 self.seconds
149 )
150 }
151}
152
153#[cfg(feature = "std")]
154impl std::error::Error for TimeOverflowError {}