bitcoin_primitives/script/
owned.rs1use core::convert::Infallible;
4use core::fmt;
5use core::marker::PhantomData;
6use core::ops::{Deref, DerefMut};
7
8#[cfg(feature = "arbitrary")]
9use arbitrary::{Arbitrary, Unstructured};
10use encoding::{ByteVecDecoder, ByteVecDecoderError, Decodable, Decoder};
11use internals::write_err;
12
13use super::Script;
14use crate::prelude::{Box, Vec};
15
16#[derive(Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
40pub struct ScriptBuf<T>(PhantomData<T>, Vec<u8>);
41
42impl<T> ScriptBuf<T> {
43 #[inline]
45 pub const fn new() -> Self { Self::from_bytes(Vec::new()) }
46
47 #[inline]
52 pub const fn from_bytes(bytes: Vec<u8>) -> Self { Self(PhantomData, bytes) }
53
54 #[inline]
56 pub fn as_script(&self) -> &Script<T> { Script::from_bytes(&self.1) }
57
58 #[inline]
60 pub fn as_mut_script(&mut self) -> &mut Script<T> { Script::from_bytes_mut(&mut self.1) }
61
62 #[inline]
70 pub fn into_bytes(self) -> Vec<u8> { self.1 }
71
72 #[must_use]
79 #[inline]
80 pub fn into_boxed_script(self) -> Box<Script<T>> {
81 Script::from_boxed_bytes(self.into_bytes().into_boxed_slice())
82 }
83
84 #[inline]
86 pub fn with_capacity(capacity: usize) -> Self { Self::from_bytes(Vec::with_capacity(capacity)) }
87
88 #[inline]
99 pub fn reserve(&mut self, additional_len: usize) { self.1.reserve(additional_len); }
100
101 #[inline]
115 pub fn reserve_exact(&mut self, additional_len: usize) { self.1.reserve_exact(additional_len); }
116
117 #[inline]
121 pub fn capacity(&self) -> usize { self.1.capacity() }
122
123 #[cfg(feature = "alloc")]
130 #[cfg(feature = "hex")]
131 #[inline]
132 #[deprecated(since = "1.0.0-rc.0", note = "use `format!(\"{var:x}\")` instead")]
133 pub fn to_hex(&self) -> alloc::string::String { alloc::format!("{:x}", self) }
134}
135
136impl<T> Default for ScriptBuf<T> {
138 fn default() -> Self { Self(PhantomData, Vec::new()) }
139}
140
141impl<T> Deref for ScriptBuf<T> {
142 type Target = Script<T>;
143
144 #[inline]
145 fn deref(&self) -> &Self::Target { self.as_script() }
146}
147
148impl<T> DerefMut for ScriptBuf<T> {
149 #[inline]
150 fn deref_mut(&mut self) -> &mut Self::Target { self.as_mut_script() }
151}
152
153pub struct ScriptBufDecoder<T>(ByteVecDecoder, PhantomData<T>);
155
156impl<T> ScriptBufDecoder<T> {
157 pub const fn new() -> Self { Self(ByteVecDecoder::new(), PhantomData) }
159}
160
161impl<T> Default for ScriptBufDecoder<T> {
162 fn default() -> Self { Self::new() }
163}
164
165impl<T> Decoder for ScriptBufDecoder<T> {
166 type Output = ScriptBuf<T>;
167 type Error = ScriptBufDecoderError;
168
169 #[inline]
170 fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<bool, Self::Error> {
171 Ok(self.0.push_bytes(bytes)?)
172 }
173
174 #[inline]
175 fn end(self) -> Result<Self::Output, Self::Error> { Ok(ScriptBuf::from_bytes(self.0.end()?)) }
176
177 #[inline]
178 fn read_limit(&self) -> usize { self.0.read_limit() }
179}
180
181impl<T> Decodable for ScriptBuf<T> {
182 type Decoder = ScriptBufDecoder<T>;
183 fn decoder() -> Self::Decoder { ScriptBufDecoder(ByteVecDecoder::new(), PhantomData) }
184}
185
186#[derive(Debug, Clone, PartialEq, Eq)]
188pub struct ScriptBufDecoderError(ByteVecDecoderError);
189
190impl From<Infallible> for ScriptBufDecoderError {
191 fn from(never: Infallible) -> Self { match never {} }
192}
193
194impl From<ByteVecDecoderError> for ScriptBufDecoderError {
195 fn from(e: ByteVecDecoderError) -> Self { Self(e) }
196}
197
198impl fmt::Display for ScriptBufDecoderError {
199 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write_err!(f, "decoder error"; self.0) }
200}
201
202#[cfg(feature = "std")]
203impl std::error::Error for ScriptBufDecoderError {
204 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
205}
206
207#[cfg(feature = "arbitrary")]
208impl<'a, T> Arbitrary<'a> for ScriptBuf<T> {
209 #[inline]
210 fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
211 let v = Vec::<u8>::arbitrary(u)?;
212 Ok(Self::from_bytes(v))
213 }
214}
215
216#[cfg(test)]
217mod tests {
218 type ScriptBuf = super::super::ScriptSigBuf;
220
221 #[cfg(feature = "alloc")]
222 use alloc::string::ToString;
223 #[cfg(feature = "alloc")]
224 use alloc::vec;
225 #[cfg(feature = "std")]
226 use std::error::Error as _;
227
228 use super::*;
229
230 #[test]
231 fn script_buf_from_bytes() {
232 let bytes = vec![1, 2, 3];
233 let script = ScriptBuf::from_bytes(bytes.clone());
234 assert_eq!(script.as_bytes(), bytes);
235 }
236
237 #[test]
238 fn script_buf_as_script() {
239 let bytes = vec![1, 2, 3];
240 let script = ScriptBuf::from_bytes(bytes.clone());
241 let script_ref = script.as_script();
242 assert_eq!(script_ref.as_bytes(), bytes);
243 }
244
245 #[test]
246 fn script_buf_as_mut_script() {
247 let mut script = ScriptBuf::from_bytes(vec![1, 2, 3]);
248 let script_mut_ref = script.as_mut_script();
249 script_mut_ref.as_mut_bytes()[0] = 4;
250 assert_eq!(script.as_mut_bytes(), &[4, 2, 3]);
251 }
252
253 #[test]
254 fn script_buf_into_bytes() {
255 let bytes = vec![1, 2, 3];
256 let script = ScriptBuf::from_bytes(bytes.clone());
257 let result = script.into_bytes();
258 assert_eq!(result, bytes);
259 }
260
261 #[test]
262 fn script_buf_into_boxed_script() {
263 let bytes = vec![1, 2, 3];
264 let script = ScriptBuf::from_bytes(bytes.clone());
265 let boxed_script = script.into_boxed_script();
266 assert_eq!(boxed_script.as_bytes(), bytes);
267 }
268
269 #[test]
270 fn script_buf_capacity() {
271 let script = ScriptBuf::with_capacity(10);
272 assert!(script.capacity() >= 10);
273 }
274
275 #[test]
276 fn script_buf_reserve() {
277 let mut script = ScriptBuf::new();
278 script.reserve(10);
279 assert!(script.capacity() >= 10);
280 }
281
282 #[test]
283 fn script_buf_reserve_exact() {
284 let mut script = ScriptBuf::new();
285 script.reserve_exact(10);
286 assert!(script.capacity() >= 10);
287 }
288
289 #[test]
290 fn script_buf_default() {
291 let script: ScriptBuf = ScriptBuf::default();
292 assert!(script.is_empty());
293 }
294
295 #[test]
296 fn script_consensus_decode_empty() {
297 let bytes = vec![0_u8];
298 let mut push = bytes.as_slice();
299 let mut decoder = ScriptBuf::decoder();
300 decoder.push_bytes(&mut push).unwrap();
301
302 let got = decoder.end().unwrap();
303 let want = ScriptBuf::new();
304
305 assert_eq!(got, want);
306 }
307
308 #[test]
309 fn script_consensus_decode_empty_with_more_data() {
310 let bytes = vec![0x00_u8, 0xff, 0xff, 0xff, 0xff];
312 let mut push = bytes.as_slice();
313 let mut decoder = ScriptBuf::decoder();
314 decoder.push_bytes(&mut push).unwrap();
315
316 let got = decoder.end().unwrap();
317 let want = ScriptBuf::new();
318
319 assert_eq!(got, want);
320 }
321
322 #[test]
323 fn decoder_full_read_limit() {
324 let mut decoder = ScriptBuf::decoder();
325 assert_eq!(decoder.read_limit(), 1);
327
328 let mut push = [32_u8].as_slice();
330 decoder.push_bytes(&mut push).unwrap();
331 assert_eq!(decoder.read_limit(), 32);
333
334 let mut push = [0xAA_u8].as_slice();
336 decoder.push_bytes(&mut push).unwrap();
337 assert_eq!(decoder.read_limit(), 31);
338 }
339
340 #[test]
341 #[cfg(feature = "alloc")]
342 fn decoder_error_display() {
343 let bytes = vec![0x01_u8];
344 let mut push = bytes.as_slice();
345 let mut decoder = <ScriptBuf as Decodable>::Decoder::default();
346 decoder.push_bytes(&mut push).unwrap();
347
348 let err = decoder.end().unwrap_err();
349 assert!(!err.to_string().is_empty());
350 #[cfg(feature = "std")]
351 assert!(err.source().is_some());
352 }
353}