bitcoin/taproot/
serialized_signature.rs1use core::borrow::Borrow;
9use core::{fmt, ops};
10
11pub use into_iter::IntoIter;
12use io::Write;
13
14use super::{SigFromSliceError, Signature};
15
16pub(crate) const MAX_LEN: usize = 65; #[derive(Copy, Clone)]
20pub struct SerializedSignature {
21 data: [u8; MAX_LEN],
22 len: usize,
23}
24
25impl fmt::Debug for SerializedSignature {
26 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(self, f) }
27}
28
29impl fmt::Display for SerializedSignature {
30 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31 hex::fmt_hex_exact!(f, MAX_LEN, self, hex::Case::Lower)
32 }
33}
34
35impl PartialEq for SerializedSignature {
36 #[inline]
37 fn eq(&self, other: &SerializedSignature) -> bool { **self == **other }
38}
39
40impl PartialEq<[u8]> for SerializedSignature {
41 #[inline]
42 fn eq(&self, other: &[u8]) -> bool { **self == *other }
43}
44
45impl PartialEq<SerializedSignature> for [u8] {
46 #[inline]
47 fn eq(&self, other: &SerializedSignature) -> bool { *self == **other }
48}
49
50impl PartialOrd for SerializedSignature {
51 fn partial_cmp(&self, other: &SerializedSignature) -> Option<core::cmp::Ordering> {
52 Some((**self).cmp(&**other))
53 }
54}
55
56impl Ord for SerializedSignature {
57 fn cmp(&self, other: &SerializedSignature) -> core::cmp::Ordering { (**self).cmp(&**other) }
58}
59
60impl PartialOrd<[u8]> for SerializedSignature {
61 fn partial_cmp(&self, other: &[u8]) -> Option<core::cmp::Ordering> {
62 (**self).partial_cmp(other)
63 }
64}
65
66impl PartialOrd<SerializedSignature> for [u8] {
67 fn partial_cmp(&self, other: &SerializedSignature) -> Option<core::cmp::Ordering> {
68 self.partial_cmp(&**other)
69 }
70}
71
72impl core::hash::Hash for SerializedSignature {
73 fn hash<H: core::hash::Hasher>(&self, state: &mut H) { (**self).hash(state) }
74}
75
76impl AsRef<[u8]> for SerializedSignature {
77 #[inline]
78 fn as_ref(&self) -> &[u8] { self }
79}
80
81impl Borrow<[u8]> for SerializedSignature {
82 #[inline]
83 fn borrow(&self) -> &[u8] { self }
84}
85
86impl ops::Deref for SerializedSignature {
87 type Target = [u8];
88
89 #[inline]
90 fn deref(&self) -> &[u8] { &self.data[..self.len] }
91}
92
93impl Eq for SerializedSignature {}
94
95impl IntoIterator for SerializedSignature {
96 type IntoIter = IntoIter;
97 type Item = u8;
98
99 #[inline]
100 fn into_iter(self) -> Self::IntoIter { IntoIter::new(self) }
101}
102
103impl<'a> IntoIterator for &'a SerializedSignature {
104 type IntoIter = core::slice::Iter<'a, u8>;
105 type Item = &'a u8;
106
107 #[inline]
108 fn into_iter(self) -> Self::IntoIter { self.iter() }
109}
110
111impl From<Signature> for SerializedSignature {
112 fn from(value: Signature) -> Self { Self::from_signature(&value) }
113}
114
115impl<'a> From<&'a Signature> for SerializedSignature {
116 fn from(value: &'a Signature) -> Self { Self::from_signature(value) }
117}
118
119impl TryFrom<SerializedSignature> for Signature {
120 type Error = SigFromSliceError;
121
122 fn try_from(value: SerializedSignature) -> Result<Self, Self::Error> { value.to_signature() }
123}
124
125impl<'a> TryFrom<&'a SerializedSignature> for Signature {
126 type Error = SigFromSliceError;
127
128 fn try_from(value: &'a SerializedSignature) -> Result<Self, Self::Error> {
129 value.to_signature()
130 }
131}
132
133impl SerializedSignature {
134 #[inline]
140 pub(crate) fn from_raw_parts(data: [u8; MAX_LEN], len: usize) -> Self {
141 assert!(len <= MAX_LEN, "attempt to set length to {} but the maximum is {}", len, MAX_LEN);
142 SerializedSignature { data, len }
143 }
144
145 #[allow(clippy::len_without_is_empty)]
148 #[inline]
149 pub fn len(&self) -> usize { self.len }
150
151 #[inline]
153 pub(crate) fn set_len_unchecked(&mut self, len: usize) { self.len = len; }
154
155 #[inline]
158 pub fn to_signature(&self) -> Result<Signature, SigFromSliceError> {
159 Signature::from_slice(self)
160 }
161
162 #[inline]
165 pub fn from_signature(sig: &Signature) -> SerializedSignature { sig.serialize() }
166
167 #[inline]
169 pub fn write_to<W: Write + ?Sized>(&self, writer: &mut W) -> Result<(), io::Error> {
170 writer.write_all(self)
171 }
172}
173
174mod into_iter {
176 use super::*;
177
178 #[allow(missing_copy_implementations)]
183 #[derive(Debug, Clone)]
184 pub struct IntoIter {
185 signature: SerializedSignature,
186 pos: usize,
188 }
189
190 impl IntoIter {
191 #[inline]
192 pub(crate) fn new(signature: SerializedSignature) -> Self {
193 IntoIter {
194 signature,
195 pos: 0,
197 }
198 }
199
200 #[inline]
204 pub fn as_slice(&self) -> &[u8] { &self.signature[self.pos..] }
205 }
206
207 impl Iterator for IntoIter {
208 type Item = u8;
209
210 #[inline]
211 fn next(&mut self) -> Option<Self::Item> {
212 let byte = *self.signature.get(self.pos)?;
213 self.pos += 1;
215 Some(byte)
216 }
217
218 #[inline]
219 fn size_hint(&self) -> (usize, Option<usize>) {
220 let len = self.signature.len() - self.pos;
222 (len, Some(len))
223 }
224
225 #[inline]
227 fn nth(&mut self, n: usize) -> Option<Self::Item> {
228 if n >= self.len() {
229 self.pos = self.signature.len();
231 None
232 } else {
233 self.pos += n;
236 self.next()
237 }
238 }
239 }
240
241 impl ExactSizeIterator for IntoIter {}
242
243 impl core::iter::FusedIterator for IntoIter {}
244
245 impl DoubleEndedIterator for IntoIter {
246 #[inline]
247 fn next_back(&mut self) -> Option<Self::Item> {
248 if self.pos == self.signature.len() {
249 return None;
250 }
251
252 let new_len = self.signature.len() - 1;
255 let byte = self.signature[new_len];
256 self.signature.set_len_unchecked(new_len);
257 Some(byte)
258 }
259 }
260}
261
262#[cfg(test)]
263mod tests {
264 use super::{SerializedSignature, MAX_LEN};
265
266 #[test]
267 fn iterator_ops_are_homomorphic() {
268 let mut fake_signature_data = [0; MAX_LEN];
269 for (i, byte) in fake_signature_data.iter_mut().enumerate() {
270 *byte = i as u8;
271 }
272
273 let fake_signature = SerializedSignature { data: fake_signature_data, len: MAX_LEN };
274
275 let mut iter1 = fake_signature.into_iter();
276 let mut iter2 = fake_signature.iter();
277
278 while let (Some(a), Some(b)) = (iter1.next(), iter2.next()) {
280 assert_eq!(a, *b);
281 assert_eq!(iter1.size_hint(), iter2.size_hint());
282 assert_eq!(iter1.as_slice(), iter2.as_slice());
283 }
284
285 let mut iter1 = fake_signature.into_iter();
286 let mut iter2 = fake_signature.iter();
287
288 while let (Some(a), Some(b)) = (iter1.next_back(), iter2.next_back()) {
291 assert_eq!(a, *b);
292 assert_eq!(iter1.size_hint(), iter2.size_hint());
293 assert_eq!(iter1.as_slice(), iter2.as_slice());
294 }
295 }
296}