bitcoin/blockdata/script/
push_bytes.rs1use core::ops::{Deref, DerefMut};
6
7#[allow(unused)]
8use crate::prelude::*;
9
10#[rustfmt::skip] #[doc(inline)]
12pub use self::primitive::*;
13
14mod primitive {
17 use core::ops::{
18 Bound, Index, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive,
19 };
20
21 use super::PushBytesError;
22 #[allow(unused)]
23 use crate::prelude::*;
24
25 #[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
26 fn check_limit(_: usize) -> Result<(), PushBytesError> { Ok(()) }
27
28 #[cfg(not(any(target_pointer_width = "16", target_pointer_width = "32")))]
29 fn check_limit(len: usize) -> Result<(), PushBytesError> {
30 if len < 0x100000000 {
31 Ok(())
32 } else {
33 Err(PushBytesError { len })
34 }
35 }
36
37 #[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
43 #[repr(transparent)]
44 pub struct PushBytes([u8]);
45
46 impl PushBytes {
47 unsafe fn from_slice_unchecked(bytes: &[u8]) -> &Self {
53 &*(bytes as *const [u8] as *const PushBytes)
54 }
55
56 unsafe fn from_mut_slice_unchecked(bytes: &mut [u8]) -> &mut Self {
62 &mut *(bytes as *mut [u8] as *mut PushBytes)
63 }
64
65 pub fn empty() -> &'static Self {
67 unsafe { Self::from_slice_unchecked(&[]) }
69 }
70
71 pub fn as_bytes(&self) -> &[u8] { &self.0 }
73
74 pub fn as_mut_bytes(&mut self) -> &mut [u8] { &mut self.0 }
76 }
77
78 macro_rules! delegate_index {
79 ($($type:ty),* $(,)?) => {
80 $(
81 impl Index<$type> for PushBytes {
83 type Output = Self;
84
85 #[inline]
86 #[track_caller]
87 fn index(&self, index: $type) -> &Self::Output {
88 unsafe {
90 Self::from_slice_unchecked(&self.0[index])
91 }
92 }
93 }
94 )*
95 }
96 }
97
98 delegate_index!(
99 Range<usize>,
100 RangeFrom<usize>,
101 RangeTo<usize>,
102 RangeFull,
103 RangeInclusive<usize>,
104 RangeToInclusive<usize>,
105 (Bound<usize>, Bound<usize>)
106 );
107
108 impl Index<usize> for PushBytes {
109 type Output = u8;
110
111 #[inline]
112 #[track_caller]
113 fn index(&self, index: usize) -> &Self::Output { &self.0[index] }
114 }
115
116 impl<'a> TryFrom<&'a [u8]> for &'a PushBytes {
117 type Error = PushBytesError;
118
119 fn try_from(bytes: &'a [u8]) -> Result<Self, Self::Error> {
120 check_limit(bytes.len())?;
121 Ok(unsafe { PushBytes::from_slice_unchecked(bytes) })
123 }
124 }
125
126 impl<'a> TryFrom<&'a mut [u8]> for &'a mut PushBytes {
127 type Error = PushBytesError;
128
129 fn try_from(bytes: &'a mut [u8]) -> Result<Self, Self::Error> {
130 check_limit(bytes.len())?;
131 Ok(unsafe { PushBytes::from_mut_slice_unchecked(bytes) })
133 }
134 }
135
136 macro_rules! from_array {
137 ($($len:literal),* $(,)?) => {
138 $(
139 impl<'a> From<&'a [u8; $len]> for &'a PushBytes {
140 fn from(bytes: &'a [u8; $len]) -> Self {
141 const _: () = [(); 1][($len >= 0x100000000u64) as usize];
143 unsafe { PushBytes::from_slice_unchecked(bytes) }
145 }
146 }
147
148 impl<'a> From<&'a mut [u8; $len]> for &'a mut PushBytes {
149 fn from(bytes: &'a mut [u8; $len]) -> Self {
150 unsafe { PushBytes::from_mut_slice_unchecked(bytes) }
153 }
154 }
155
156 impl AsRef<PushBytes> for [u8; $len] {
157 fn as_ref(&self) -> &PushBytes {
158 self.into()
159 }
160 }
161
162 impl AsMut<PushBytes> for [u8; $len] {
163 fn as_mut(&mut self) -> &mut PushBytes {
164 self.into()
165 }
166 }
167
168 impl From<[u8; $len]> for PushBytesBuf {
169 fn from(bytes: [u8; $len]) -> Self {
170 PushBytesBuf(Vec::from(&bytes as &[_]))
171 }
172 }
173
174 impl<'a> From<&'a [u8; $len]> for PushBytesBuf {
175 fn from(bytes: &'a [u8; $len]) -> Self {
176 PushBytesBuf(Vec::from(bytes as &[_]))
177 }
178 }
179 )*
180 }
181 }
182
183 from_array! {
185 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
186 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
187 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
188 71, 72, 73, 74, 75, 76
189 }
190
191 #[derive(Default, Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
193 pub struct PushBytesBuf(Vec<u8>);
194
195 impl PushBytesBuf {
196 #[inline]
198 pub const fn new() -> Self { PushBytesBuf(Vec::new()) }
199
200 pub fn with_capacity(capacity: usize) -> Self { PushBytesBuf(Vec::with_capacity(capacity)) }
202
203 pub fn reserve(&mut self, additional_capacity: usize) {
205 self.0.reserve(additional_capacity)
206 }
207
208 #[allow(deprecated)]
214 pub fn push(&mut self, byte: u8) -> Result<(), PushBytesError> {
215 check_limit(self.0.len().saturating_add(1))?;
217 self.0.push(byte);
218 Ok(())
219 }
220
221 pub fn extend_from_slice(&mut self, bytes: &[u8]) -> Result<(), PushBytesError> {
227 let len = self.0.len().saturating_add(bytes.len());
228 check_limit(len)?;
229 self.0.extend_from_slice(bytes);
230 Ok(())
231 }
232
233 pub fn pop(&mut self) -> Option<u8> { self.0.pop() }
235
236 #[track_caller]
242 pub fn remove(&mut self, index: usize) -> u8 { self.0.remove(index) }
243
244 pub fn clear(&mut self) { self.0.clear() }
246
247 pub fn truncate(&mut self, len: usize) { self.0.truncate(len) }
249
250 pub fn as_push_bytes(&self) -> &PushBytes {
252 unsafe { PushBytes::from_slice_unchecked(&self.0) }
254 }
255
256 pub fn as_mut_push_bytes(&mut self) -> &mut PushBytes {
258 unsafe { PushBytes::from_mut_slice_unchecked(&mut self.0) }
260 }
261
262 pub(super) fn inner(&self) -> &Vec<u8> { &self.0 }
264 }
265
266 impl From<PushBytesBuf> for Vec<u8> {
267 fn from(value: PushBytesBuf) -> Self { value.0 }
268 }
269
270 impl TryFrom<Vec<u8>> for PushBytesBuf {
271 type Error = PushBytesError;
272
273 fn try_from(vec: Vec<u8>) -> Result<Self, Self::Error> {
274 let _: &PushBytes = vec.as_slice().try_into()?;
276 Ok(PushBytesBuf(vec))
277 }
278 }
279
280 impl ToOwned for PushBytes {
281 type Owned = PushBytesBuf;
282
283 fn to_owned(&self) -> Self::Owned { PushBytesBuf(self.0.to_owned()) }
284 }
285}
286
287impl PushBytes {
288 pub fn len(&self) -> usize { self.as_bytes().len() }
290
291 pub fn is_empty(&self) -> bool { self.as_bytes().is_empty() }
293}
294
295impl PushBytesBuf {
296 pub fn len(&self) -> usize { self.inner().len() }
298
299 pub fn capacity(&self) -> usize { self.inner().capacity() }
301
302 pub fn is_empty(&self) -> bool { self.inner().is_empty() }
304}
305
306impl AsRef<[u8]> for PushBytes {
307 fn as_ref(&self) -> &[u8] { self.as_bytes() }
308}
309
310impl AsMut<[u8]> for PushBytes {
311 fn as_mut(&mut self) -> &mut [u8] { self.as_mut_bytes() }
312}
313
314impl Deref for PushBytesBuf {
315 type Target = PushBytes;
316
317 fn deref(&self) -> &Self::Target { self.as_push_bytes() }
318}
319
320impl DerefMut for PushBytesBuf {
321 fn deref_mut(&mut self) -> &mut Self::Target { self.as_mut_push_bytes() }
322}
323
324impl AsRef<PushBytes> for PushBytes {
325 fn as_ref(&self) -> &PushBytes { self }
326}
327
328impl AsMut<PushBytes> for PushBytes {
329 fn as_mut(&mut self) -> &mut PushBytes { self }
330}
331
332impl AsRef<PushBytes> for PushBytesBuf {
333 fn as_ref(&self) -> &PushBytes { self.as_push_bytes() }
334}
335
336impl AsMut<PushBytes> for PushBytesBuf {
337 fn as_mut(&mut self) -> &mut PushBytes { self.as_mut_push_bytes() }
338}
339
340impl Borrow<PushBytes> for PushBytesBuf {
341 fn borrow(&self) -> &PushBytes { self.as_push_bytes() }
342}
343
344impl BorrowMut<PushBytes> for PushBytesBuf {
345 fn borrow_mut(&mut self) -> &mut PushBytes { self.as_mut_push_bytes() }
346}
347
348pub trait PushBytesErrorReport {
353 fn input_len(&self) -> usize;
355}
356
357impl PushBytesErrorReport for core::convert::Infallible {
358 #[inline]
359 fn input_len(&self) -> usize { match *self {} }
360}
361
362pub use error::*;
363
364#[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
365mod error {
366 use core::fmt;
367
368 #[allow(unused)]
370 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
371 pub struct PushBytesError {
372 never: core::convert::Infallible,
373 }
374
375 impl super::PushBytesErrorReport for PushBytesError {
376 #[inline]
377 fn input_len(&self) -> usize { match self.never {} }
378 }
379
380 impl fmt::Display for PushBytesError {
381 fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { match self.never {} }
382 }
383}
384
385#[cfg(not(any(target_pointer_width = "16", target_pointer_width = "32")))]
388mod error {
389 use core::fmt;
390
391 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
393 pub struct PushBytesError {
394 pub(super) len: usize,
396 }
397
398 impl super::PushBytesErrorReport for PushBytesError {
399 #[inline]
400 fn input_len(&self) -> usize { self.len }
401 }
402
403 impl fmt::Display for PushBytesError {
404 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
405 write!(
406 f,
407 "attempt to prepare {} bytes to be pushed into script but the limit is 2^32-1",
408 self.len
409 )
410 }
411 }
412}
413
414#[cfg(feature = "std")]
415impl std::error::Error for PushBytesError {
416 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
417}