1use std::ops::{Add, AddAssign};
2
3use derive_more::{Deref, DerefMut};
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6use vecdb::{CheckedSub, Formattable, Pco, PrintableIndex};
7
8use super::Vin;
9
10#[derive(
11 Debug,
12 PartialEq,
13 Eq,
14 PartialOrd,
15 Ord,
16 Clone,
17 Copy,
18 Deref,
19 DerefMut,
20 Default,
21 Serialize,
22 Deserialize,
23 Pco,
24 JsonSchema,
25)]
26pub struct TxInIndex(u64);
27
28impl TxInIndex {
29 pub const UNSPENT: Self = Self(u64::MAX);
31
32 pub fn new(index: u64) -> Self {
33 Self(index)
34 }
35
36 pub fn incremented(self) -> Self {
37 Self(*self + 1)
38 }
39
40 pub fn is_unspent(self) -> bool {
41 self == Self::UNSPENT
42 }
43}
44
45impl Add<TxInIndex> for TxInIndex {
46 type Output = Self;
47 fn add(self, rhs: TxInIndex) -> Self::Output {
48 Self(self.0 + rhs.0)
49 }
50}
51
52impl Add<Vin> for TxInIndex {
53 type Output = Self;
54 fn add(self, rhs: Vin) -> Self::Output {
55 Self(self.0 + u64::from(rhs))
56 }
57}
58
59impl Add<usize> for TxInIndex {
60 type Output = Self;
61 fn add(self, rhs: usize) -> Self::Output {
62 Self(self.0 + rhs as u64)
63 }
64}
65
66impl AddAssign<TxInIndex> for TxInIndex {
67 fn add_assign(&mut self, rhs: TxInIndex) {
68 self.0 += rhs.0
69 }
70}
71
72impl CheckedSub<TxInIndex> for TxInIndex {
73 fn checked_sub(self, rhs: Self) -> Option<Self> {
74 self.0.checked_sub(rhs.0).map(Self::from)
75 }
76}
77
78impl From<TxInIndex> for u32 {
79 #[inline]
80 fn from(value: TxInIndex) -> Self {
81 if value.0 > u32::MAX as u64 {
82 panic!()
83 }
84 value.0 as u32
85 }
86}
87
88impl From<u64> for TxInIndex {
89 #[inline]
90 fn from(value: u64) -> Self {
91 Self(value)
92 }
93}
94impl From<TxInIndex> for u64 {
95 #[inline]
96 fn from(value: TxInIndex) -> Self {
97 value.0
98 }
99}
100
101impl From<usize> for TxInIndex {
102 #[inline]
103 fn from(value: usize) -> Self {
104 Self(value as u64)
105 }
106}
107impl From<TxInIndex> for usize {
108 #[inline]
109 fn from(value: TxInIndex) -> Self {
110 value.0 as usize
111 }
112}
113
114impl PrintableIndex for TxInIndex {
115 fn to_string() -> &'static str {
116 "txin_index"
117 }
118
119 fn to_possible_strings() -> &'static [&'static str] {
120 &["txi", "txin", "txin_index"]
121 }
122}
123
124impl std::fmt::Display for TxInIndex {
125 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
126 let mut buf = itoa::Buffer::new();
127 let str = buf.format(self.0);
128 f.write_str(str)
129 }
130}
131
132impl Formattable for TxInIndex {
133 #[inline(always)]
134 fn write_to(&self, buf: &mut Vec<u8>) {
135 let mut b = itoa::Buffer::new();
136 buf.extend_from_slice(b.format(self.0).as_bytes());
137 }
138}