soroban_sdk/
bytes.rs

1#[cfg(feature = "alloc")]
2extern crate alloc;
3
4use core::{
5    borrow::Borrow,
6    cmp::Ordering,
7    convert::Infallible,
8    fmt::Debug,
9    iter::FusedIterator,
10    ops::{Bound, RangeBounds},
11};
12
13use super::{
14    env::internal::{BytesObject, Env as _, EnvBase as _},
15    env::IntoVal,
16    ConversionError, Env, TryFromVal, TryIntoVal, Val,
17};
18
19use crate::unwrap::{UnwrapInfallible, UnwrapOptimized};
20#[cfg(doc)]
21use crate::{storage::Storage, Map, Vec};
22
23#[cfg(not(target_family = "wasm"))]
24use super::xdr::ScVal;
25
26/// Create a [Bytes] with an array, or an integer or hex literal.
27///
28/// The first argument in the list must be a reference to an [Env].
29///
30/// The second argument can be an [u8] array, or an integer literal of unbounded
31/// size in any form: base10, hex, etc.
32///
33/// ### Examples
34///
35/// ```
36/// use soroban_sdk::{Env, bytes};
37///
38/// let env = Env::default();
39/// let bytes = bytes!(&env, 0xfded3f55dec47250a52a8c0bb7038e72fa6ffaae33562f77cd2b629ef7fd424d);
40/// assert_eq!(bytes.len(), 32);
41/// ```
42///
43/// ```
44/// use soroban_sdk::{Env, bytes};
45///
46/// let env = Env::default();
47/// let bytes = bytes!(&env, [2, 0]);
48/// assert_eq!(bytes.len(), 2);
49/// ```
50///
51/// ```
52/// use soroban_sdk::{Env, bytes};
53///
54/// let env = Env::default();
55/// let bytes = bytes!(&env);
56/// assert_eq!(bytes.len(), 0);
57/// ```
58#[macro_export]
59macro_rules! bytes {
60    ($env:expr $(,)?) => {
61        $crate::Bytes::new($env)
62    };
63    ($env:expr, [$($x:expr),+ $(,)?] $(,)?) => {
64        $crate::Bytes::from_array($env, &[$($x),+])
65    };
66    ($env:expr, $x:tt $(,)?) => {
67        $crate::Bytes::from_array($env, &$crate::reexports_for_macros::bytes_lit::bytes!($x))
68    };
69}
70
71/// Create a [BytesN] with an array, or an integer or hex literal.
72///
73/// The first argument in the list must be a reference to an [Env].
74///
75/// The second argument can be an [u8] array, or an integer literal of unbounded
76/// size in any form: base10, hex, etc.
77///
78/// ### Examples
79///
80/// ```
81/// use soroban_sdk::{Env, bytesn};
82///
83/// let env = Env::default();
84/// let bytes = bytesn!(&env, 0xfded3f55dec47250a52a8c0bb7038e72fa6ffaae33562f77cd2b629ef7fd424d);
85/// assert_eq!(bytes.len(), 32);
86/// ```
87///
88/// ```
89/// use soroban_sdk::{Env, bytesn};
90///
91/// let env = Env::default();
92/// let bytes = bytesn!(&env, [2, 0]);
93/// assert_eq!(bytes.len(), 2);
94/// ```
95#[macro_export]
96macro_rules! bytesn {
97    ($env:expr, [$($x:expr),+ $(,)?] $(,)?) => {
98        $crate::BytesN::from_array($env, &[$($x),+])
99    };
100    ($env:expr, $x:tt $(,)?) => {
101        $crate::BytesN::from_array($env, &$crate::reexports_for_macros::bytes_lit::bytes!($x))
102    };
103}
104
105#[macro_export]
106macro_rules! impl_bytesn_repr {
107    ($elem: ident, $size: expr) => {
108        impl $elem {
109            pub fn from_bytes(bytes: BytesN<$size>) -> Self {
110                Self(bytes)
111            }
112
113            pub fn to_bytes(&self) -> BytesN<$size> {
114                self.0.clone()
115            }
116
117            pub fn as_bytes(&self) -> &BytesN<$size> {
118                &self.0
119            }
120
121            pub fn to_array(&self) -> [u8; $size] {
122                self.0.to_array()
123            }
124
125            pub fn from_array(env: &Env, array: &[u8; $size]) -> Self {
126                Self(<BytesN<$size>>::from_array(env, array))
127            }
128
129            pub fn as_val(&self) -> &Val {
130                self.0.as_val()
131            }
132
133            pub fn to_val(&self) -> Val {
134                self.0.to_val()
135            }
136
137            pub fn as_object(&self) -> &BytesObject {
138                self.0.as_object()
139            }
140
141            pub fn to_object(&self) -> BytesObject {
142                self.0.to_object()
143            }
144        }
145
146        impl TryFromVal<Env, Val> for $elem {
147            type Error = ConversionError;
148
149            fn try_from_val(env: &Env, val: &Val) -> Result<Self, Self::Error> {
150                let bytes = <BytesN<$size>>::try_from_val(env, val)?;
151                Ok($elem(bytes))
152            }
153        }
154
155        impl TryFromVal<Env, $elem> for Val {
156            type Error = ConversionError;
157
158            fn try_from_val(_env: &Env, elt: &$elem) -> Result<Self, Self::Error> {
159                Ok(elt.to_val())
160            }
161        }
162
163        #[cfg(not(target_family = "wasm"))]
164        impl From<&$elem> for ScVal {
165            fn from(v: &$elem) -> Self {
166                Self::from(&v.0)
167            }
168        }
169
170        #[cfg(not(target_family = "wasm"))]
171        impl From<$elem> for ScVal {
172            fn from(v: $elem) -> Self {
173                (&v).into()
174            }
175        }
176
177        impl IntoVal<Env, BytesN<$size>> for $elem {
178            fn into_val(&self, _e: &Env) -> BytesN<$size> {
179                self.0.clone()
180            }
181        }
182
183        impl From<$elem> for Bytes {
184            fn from(v: $elem) -> Self {
185                v.0.into()
186            }
187        }
188
189        impl From<$elem> for BytesN<$size> {
190            fn from(v: $elem) -> Self {
191                v.0
192            }
193        }
194
195        impl Into<[u8; $size]> for $elem {
196            fn into(self) -> [u8; $size] {
197                self.0.into()
198            }
199        }
200
201        impl Eq for $elem {}
202
203        impl PartialEq for $elem {
204            fn eq(&self, other: &Self) -> bool {
205                self.0.partial_cmp(other.as_bytes()) == Some(Ordering::Equal)
206            }
207        }
208
209        impl Debug for $elem {
210            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
211                write!(f, "{}({:?})", stringify!($elem), self.to_array())
212            }
213        }
214    };
215}
216
217/// Bytes is a contiguous growable array type containing `u8`s.
218///
219/// The array is stored in the Host and available to the Guest through the
220/// functions defined on Bytes.
221///
222/// Bytes values can be stored as [Storage], or in other types like [Vec],
223/// [Map], etc.
224///
225/// ### Examples
226///
227/// Bytes values can be created from slices:
228/// ```
229/// use soroban_sdk::{Bytes, Env};
230///
231/// let env = Env::default();
232/// let bytes = Bytes::from_slice(&env, &[1; 32]);
233/// assert_eq!(bytes.len(), 32);
234/// let mut slice = [0u8; 32];
235/// bytes.copy_into_slice(&mut slice);
236/// assert_eq!(slice, [1u8; 32]);
237/// ```
238#[derive(Clone)]
239pub struct Bytes {
240    env: Env,
241    obj: BytesObject,
242}
243
244impl Debug for Bytes {
245    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
246        write!(f, "Bytes(")?;
247        let mut iter = self.iter();
248        if let Some(x) = iter.next() {
249            write!(f, "{:?}", x)?;
250        }
251        for x in iter {
252            write!(f, ", {:?}", x)?;
253        }
254        write!(f, ")")?;
255        Ok(())
256    }
257}
258
259impl Eq for Bytes {}
260
261impl PartialEq for Bytes {
262    fn eq(&self, other: &Self) -> bool {
263        self.partial_cmp(other) == Some(Ordering::Equal)
264    }
265}
266
267impl PartialOrd for Bytes {
268    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
269        Some(Ord::cmp(self, other))
270    }
271}
272
273impl Ord for Bytes {
274    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
275        #[cfg(not(target_family = "wasm"))]
276        if !self.env.is_same_env(&other.env) {
277            return ScVal::from(self).cmp(&ScVal::from(other));
278        }
279        let v = self
280            .env
281            .obj_cmp(self.obj.to_val(), other.obj.to_val())
282            .unwrap_infallible();
283        v.cmp(&0)
284    }
285}
286
287impl TryFromVal<Env, Bytes> for Bytes {
288    type Error = ConversionError;
289
290    fn try_from_val(_env: &Env, v: &Bytes) -> Result<Self, Self::Error> {
291        Ok(v.clone())
292    }
293}
294
295impl TryFromVal<Env, BytesObject> for Bytes {
296    type Error = Infallible;
297
298    fn try_from_val(env: &Env, val: &BytesObject) -> Result<Self, Self::Error> {
299        Ok(unsafe { Bytes::unchecked_new(env.clone(), *val) })
300    }
301}
302
303impl TryFromVal<Env, Val> for Bytes {
304    type Error = ConversionError;
305
306    fn try_from_val(env: &Env, val: &Val) -> Result<Self, Self::Error> {
307        Ok(BytesObject::try_from_val(env, val)?
308            .try_into_val(env)
309            .unwrap_infallible())
310    }
311}
312
313impl TryFromVal<Env, Bytes> for Val {
314    type Error = ConversionError;
315
316    fn try_from_val(_env: &Env, v: &Bytes) -> Result<Self, Self::Error> {
317        Ok(v.to_val())
318    }
319}
320
321impl TryFromVal<Env, &Bytes> for Val {
322    type Error = ConversionError;
323
324    fn try_from_val(_env: &Env, v: &&Bytes) -> Result<Self, Self::Error> {
325        Ok(v.to_val())
326    }
327}
328
329impl From<Bytes> for Val {
330    #[inline(always)]
331    fn from(v: Bytes) -> Self {
332        v.obj.into()
333    }
334}
335
336impl From<Bytes> for BytesObject {
337    #[inline(always)]
338    fn from(v: Bytes) -> Self {
339        v.obj
340    }
341}
342
343impl From<&Bytes> for BytesObject {
344    #[inline(always)]
345    fn from(v: &Bytes) -> Self {
346        v.obj
347    }
348}
349
350impl From<&Bytes> for Bytes {
351    #[inline(always)]
352    fn from(v: &Bytes) -> Self {
353        v.clone()
354    }
355}
356
357#[cfg(not(target_family = "wasm"))]
358impl From<&Bytes> for ScVal {
359    fn from(v: &Bytes) -> Self {
360        // This conversion occurs only in test utilities, and theoretically all
361        // values should convert to an ScVal because the Env won't let the host
362        // type to exist otherwise, unwrapping. Even if there are edge cases
363        // that don't, this is a trade off for a better test developer
364        // experience.
365        ScVal::try_from_val(&v.env, &v.obj.to_val()).unwrap()
366    }
367}
368
369#[cfg(not(target_family = "wasm"))]
370impl From<Bytes> for ScVal {
371    fn from(v: Bytes) -> Self {
372        (&v).into()
373    }
374}
375
376#[cfg(not(target_family = "wasm"))]
377impl TryFromVal<Env, ScVal> for Bytes {
378    type Error = ConversionError;
379    fn try_from_val(env: &Env, val: &ScVal) -> Result<Self, Self::Error> {
380        Ok(
381            BytesObject::try_from_val(env, &Val::try_from_val(env, val)?)?
382                .try_into_val(env)
383                .unwrap_infallible(),
384        )
385    }
386}
387
388impl TryFromVal<Env, &str> for Bytes {
389    type Error = ConversionError;
390
391    fn try_from_val(env: &Env, v: &&str) -> Result<Self, Self::Error> {
392        Ok(Bytes::from_slice(env, v.as_bytes()))
393    }
394}
395
396impl TryFromVal<Env, &[u8]> for Bytes {
397    type Error = ConversionError;
398
399    fn try_from_val(env: &Env, v: &&[u8]) -> Result<Self, Self::Error> {
400        Ok(Bytes::from_slice(env, v))
401    }
402}
403
404impl<const N: usize> TryFromVal<Env, [u8; N]> for Bytes {
405    type Error = ConversionError;
406
407    fn try_from_val(env: &Env, v: &[u8; N]) -> Result<Self, Self::Error> {
408        Ok(Bytes::from_array(env, v))
409    }
410}
411
412impl Bytes {
413    #[inline(always)]
414    pub(crate) unsafe fn unchecked_new(env: Env, obj: BytesObject) -> Self {
415        Self { env, obj }
416    }
417
418    #[inline(always)]
419    pub fn env(&self) -> &Env {
420        &self.env
421    }
422
423    pub fn as_val(&self) -> &Val {
424        self.obj.as_val()
425    }
426
427    pub fn to_val(&self) -> Val {
428        self.obj.to_val()
429    }
430
431    pub fn as_object(&self) -> &BytesObject {
432        &self.obj
433    }
434
435    pub fn to_object(&self) -> BytesObject {
436        self.obj
437    }
438}
439
440impl Bytes {
441    /// Create an empty Bytes.
442    #[inline(always)]
443    pub fn new(env: &Env) -> Bytes {
444        let obj = env.bytes_new().unwrap_infallible();
445        unsafe { Self::unchecked_new(env.clone(), obj) }
446    }
447
448    /// Create a Bytes from the array.
449    #[inline(always)]
450    pub fn from_array<const N: usize>(env: &Env, items: &[u8; N]) -> Bytes {
451        Self::from_slice(env, items)
452    }
453
454    /// Create a Bytes from the slice.
455    #[inline(always)]
456    pub fn from_slice(env: &Env, items: &[u8]) -> Bytes {
457        Bytes {
458            env: env.clone(),
459            obj: env.bytes_new_from_slice(items).unwrap_optimized(),
460        }
461    }
462
463    /// Sets the byte at the position with new value.
464    ///
465    /// ### Panics
466    ///
467    /// If the position is out-of-bounds.
468    #[inline(always)]
469    pub fn set(&mut self, i: u32, v: u8) {
470        let v32: u32 = v.into();
471        self.obj = self
472            .env()
473            .bytes_put(self.obj, i.into(), v32.into())
474            .unwrap_infallible()
475    }
476
477    /// Returns the byte at the position or None if out-of-bounds.
478    #[inline(always)]
479    pub fn get(&self, i: u32) -> Option<u8> {
480        if i < self.len() {
481            Some(self.get_unchecked(i))
482        } else {
483            None
484        }
485    }
486
487    /// Returns the byte at the position.
488    ///
489    /// ### Panics
490    ///
491    /// If the position is out-of-bounds.
492    #[inline(always)]
493    pub fn get_unchecked(&self, i: u32) -> u8 {
494        let res32_val = self.env().bytes_get(self.obj, i.into()).unwrap_infallible();
495        let res32: u32 = res32_val.into();
496        res32 as u8
497    }
498
499    /// Returns true if the Bytes is empty and has a length of zero.
500    #[inline(always)]
501    pub fn is_empty(&self) -> bool {
502        self.len() == 0
503    }
504
505    /// Returns the number of bytes are in the Bytes.
506    #[inline(always)]
507    pub fn len(&self) -> u32 {
508        self.env().bytes_len(self.obj).unwrap_infallible().into()
509    }
510
511    /// Returns the first byte or None if empty.
512    #[inline(always)]
513    pub fn first(&self) -> Option<u8> {
514        if !self.is_empty() {
515            Some(self.first_unchecked())
516        } else {
517            None
518        }
519    }
520
521    /// Returns the first byte.
522    ///
523    /// ### Panics
524    ///
525    /// If the Bytes is empty.
526    #[inline(always)]
527    pub fn first_unchecked(&self) -> u8 {
528        let res: u32 = self.env().bytes_front(self.obj).unwrap_infallible().into();
529        res as u8
530    }
531
532    /// Returns the last byte or None if empty.
533    #[inline(always)]
534    pub fn last(&self) -> Option<u8> {
535        if !self.is_empty() {
536            Some(self.last_unchecked())
537        } else {
538            None
539        }
540    }
541
542    /// Returns the last byte.
543    ///
544    /// ### Panics
545    ///
546    /// If the Bytes is empty.
547    #[inline(always)]
548    pub fn last_unchecked(&self) -> u8 {
549        let res: u32 = self.env().bytes_back(self.obj).unwrap_infallible().into();
550        res as u8
551    }
552
553    /// Removes the byte at the position.
554    ///
555    /// Returns `None` if out-of-bounds.
556    #[inline(always)]
557    pub fn remove(&mut self, i: u32) -> Option<()> {
558        if i < self.len() {
559            self.remove_unchecked(i);
560            Some(())
561        } else {
562            None
563        }
564    }
565
566    /// Removes the byte at the position.
567    ///
568    /// ### Panics
569    ///
570    /// If the position is out-of-bounds.
571    #[inline(always)]
572    pub fn remove_unchecked(&mut self, i: u32) {
573        self.obj = self.env().bytes_del(self.obj, i.into()).unwrap_infallible()
574    }
575
576    /// Adds the byte to the back.
577    ///
578    /// Increases the length by one and puts the byte in the last position.
579    #[inline(always)]
580    pub fn push_back(&mut self, x: u8) {
581        let x32: u32 = x.into();
582        self.obj = self
583            .env()
584            .bytes_push(self.obj, x32.into())
585            .unwrap_infallible()
586    }
587
588    /// Removes and returns the last byte or None if empty.
589    #[inline(always)]
590    pub fn pop_back(&mut self) -> Option<u8> {
591        let last = self.last()?;
592        self.obj = self.env().bytes_pop(self.obj).unwrap_infallible();
593        Some(last)
594    }
595
596    /// Removes and returns the last byte or None if empty.
597    ///
598    /// ### Panics
599    ///
600    /// If the Bytes is empty.
601    #[inline(always)]
602    pub fn pop_back_unchecked(&mut self) -> u8 {
603        let last = self.last_unchecked();
604        self.obj = self.env().bytes_pop(self.obj).unwrap_infallible();
605        last
606    }
607
608    /// Insert the byte at the position.
609    ///
610    /// ### Panics
611    ///
612    /// If the position is out-of-bounds.
613    #[inline(always)]
614    pub fn insert(&mut self, i: u32, b: u8) {
615        let b32: u32 = b.into();
616        self.obj = self
617            .env()
618            .bytes_insert(self.obj, i.into(), b32.into())
619            .unwrap_infallible()
620    }
621
622    /// Insert the bytes at the position.
623    ///
624    /// ### Panics
625    ///
626    /// If the position is out-of-bounds.
627    #[inline(always)]
628    pub fn insert_from_bytes(&mut self, i: u32, bytes: Bytes) {
629        let mut result = self.slice(..i);
630        result.append(&bytes);
631        result.append(&self.slice(i..));
632        *self = result
633    }
634
635    /// Insert the bytes at the position.
636    ///
637    /// ### Panics
638    ///
639    /// If the position is out-of-bounds.
640    #[inline(always)]
641    pub fn insert_from_array<const N: usize>(&mut self, i: u32, array: &[u8; N]) {
642        self.insert_from_slice(i, array)
643    }
644
645    /// Insert the bytes at the position.
646    ///
647    /// ### Panics
648    ///
649    /// If the position is out-of-bounds.
650    #[inline(always)]
651    pub fn insert_from_slice(&mut self, i: u32, slice: &[u8]) {
652        self.insert_from_bytes(i, Bytes::from_slice(self.env(), slice))
653    }
654
655    /// Append the bytes.
656    #[inline(always)]
657    pub fn append(&mut self, other: &Bytes) {
658        self.obj = self
659            .env()
660            .bytes_append(self.obj, other.obj)
661            .unwrap_infallible()
662    }
663
664    /// Extend with the bytes in the array.
665    #[inline(always)]
666    pub fn extend_from_array<const N: usize>(&mut self, array: &[u8; N]) {
667        self.extend_from_slice(array)
668    }
669
670    /// Extend with the bytes in the slice.
671    #[inline(always)]
672    pub fn extend_from_slice(&mut self, slice: &[u8]) {
673        self.obj = self
674            .env()
675            .bytes_copy_from_slice(self.to_object(), self.len().into(), slice)
676            .unwrap_optimized()
677    }
678
679    /// Copy the bytes from slice.
680    ///
681    /// The full number of bytes in slice are always copied and [Bytes] is grown
682    /// if necessary.
683    #[inline(always)]
684    pub fn copy_from_slice(&mut self, i: u32, slice: &[u8]) {
685        self.obj = self
686            .env()
687            .bytes_copy_from_slice(self.to_object(), i.into(), slice)
688            .unwrap_optimized()
689    }
690
691    /// Copy the bytes into the given slice.
692    ///
693    /// ### Panics
694    ///
695    /// If the output slice and bytes are of different lengths.
696    #[inline(always)]
697    pub fn copy_into_slice(&self, slice: &mut [u8]) {
698        let env = self.env();
699        if self.len() as usize != slice.len() {
700            sdk_panic!("Bytes::copy_into_slice with mismatched slice length")
701        }
702        env.bytes_copy_to_slice(self.to_object(), Val::U32_ZERO, slice)
703            .unwrap_optimized();
704    }
705
706    /// Returns a subset of the bytes as defined by the start and end bounds of
707    /// the range.
708    ///
709    /// ### Panics
710    ///
711    /// If the range is out-of-bounds.
712    #[must_use]
713    pub fn slice(&self, r: impl RangeBounds<u32>) -> Self {
714        let start_bound = match r.start_bound() {
715            Bound::Included(s) => *s,
716            Bound::Excluded(s) => *s + 1,
717            Bound::Unbounded => 0,
718        };
719        let end_bound = match r.end_bound() {
720            Bound::Included(s) => *s + 1,
721            Bound::Excluded(s) => *s,
722            Bound::Unbounded => self.len(),
723        };
724        let env = self.env();
725        let bin = env
726            .bytes_slice(self.obj, start_bound.into(), end_bound.into())
727            .unwrap_infallible();
728        unsafe { Self::unchecked_new(env.clone(), bin) }
729    }
730
731    pub fn iter(&self) -> BytesIter {
732        self.clone().into_iter()
733    }
734
735    /// Copy the bytes into a buffer of given size.
736    ///
737    /// Returns the buffer and a range of where the bytes live in the given
738    /// buffer.
739    ///
740    /// Suitable when the size of the bytes isn't a fixed size but it is known
741    /// to be under a certain size, or failure due to overflow is acceptable.
742    ///
743    /// ### Panics
744    ///
745    /// If the size of the bytes is larger than the size of the buffer. To avoid
746    /// this, first slice the bytes into a smaller size then convert to a
747    /// buffer.
748    #[must_use]
749    pub fn to_buffer<const B: usize>(&self) -> BytesBuffer<B> {
750        let mut buffer = [0u8; B];
751        let len = self.len() as usize;
752        {
753            let slice = &mut buffer[0..len];
754            self.copy_into_slice(slice);
755        }
756        BytesBuffer { buffer, len }
757    }
758
759    /// Copy the bytes into a Rust alloc Vec of size matching the bytes.
760    ///
761    /// Returns the Vec. Allocates using the built-in allocator.
762    ///
763    /// Suitable when the size of the bytes isn't a fixed size and the allocator
764    /// functionality of the sdk is enabled.
765    #[cfg(feature = "alloc")]
766    #[must_use]
767    pub fn to_alloc_vec(&self) -> alloc::vec::Vec<u8> {
768        let len = self.len() as usize;
769        let mut vec = alloc::vec::from_elem(0u8, len);
770        self.copy_into_slice(&mut vec);
771        vec
772    }
773}
774
775/// A `BytesBuffer` stores a variable number of bytes, up to a fixed limit `B`.
776///
777/// The bytes are stored in a fixed-size non-heap-allocated structure. It is a
778/// minimal wrapper around a fixed-size `[u8;B]` byte array and a length field
779/// indicating the amount of the byte array containing meaningful data.
780#[derive(Debug, Clone, PartialEq, Eq)]
781pub struct BytesBuffer<const B: usize> {
782    buffer: [u8; B],
783    len: usize,
784}
785
786impl<const B: usize> Borrow<[u8]> for BytesBuffer<B> {
787    /// Returns a borrow slice of the bytes stored in the BytesBuffer.
788    fn borrow(&self) -> &[u8] {
789        self.as_slice()
790    }
791}
792
793impl<const B: usize> BytesBuffer<B> {
794    /// Returns a borrow slice of the bytes stored in the BytesBuffer.
795    pub fn as_slice(&self) -> &[u8] {
796        &self.buffer[..self.len]
797    }
798}
799
800impl IntoIterator for Bytes {
801    type Item = u8;
802    type IntoIter = BytesIter;
803
804    fn into_iter(self) -> Self::IntoIter {
805        BytesIter(self)
806    }
807}
808
809#[derive(Clone)]
810pub struct BytesIter(Bytes);
811
812impl BytesIter {
813    fn into_bin(self) -> Bytes {
814        self.0
815    }
816}
817
818impl Iterator for BytesIter {
819    type Item = u8;
820
821    fn next(&mut self) -> Option<Self::Item> {
822        if self.0.is_empty() {
823            None
824        } else {
825            let val: u32 = self
826                .0
827                .env()
828                .bytes_front(self.0.obj)
829                .unwrap_infallible()
830                .into();
831            self.0 = self.0.slice(1..);
832            Some(val as u8)
833        }
834    }
835
836    fn size_hint(&self) -> (usize, Option<usize>) {
837        let len = self.0.len() as usize;
838        (len, Some(len))
839    }
840}
841
842impl DoubleEndedIterator for BytesIter {
843    fn next_back(&mut self) -> Option<Self::Item> {
844        let len = self.0.len();
845        if len == 0 {
846            None
847        } else {
848            let val: u32 = self
849                .0
850                .env()
851                .bytes_back(self.0.obj)
852                .unwrap_infallible()
853                .into();
854            self.0 = self.0.slice(..len - 1);
855            Some(val as u8)
856        }
857    }
858}
859
860impl FusedIterator for BytesIter {}
861
862impl ExactSizeIterator for BytesIter {
863    fn len(&self) -> usize {
864        self.0.len() as usize
865    }
866}
867
868/// BytesN is a contiguous fixed-size array type containing `u8`s.
869///
870/// The array is stored in the Host and available to the Guest through the
871/// functions defined on Bytes.
872///
873/// Bytes values can be stored as [Storage], or in other types like [Vec], [Map],
874/// etc.
875///
876/// ### Examples
877///
878/// BytesN values can be created from arrays:
879/// ```
880/// use soroban_sdk::{Bytes, BytesN, Env};
881///
882/// let env = Env::default();
883/// let bytes = BytesN::from_array(&env, &[0; 32]);
884/// assert_eq!(bytes.len(), 32);
885/// ```
886///
887/// BytesN and Bytes values are convertible:
888/// ```
889/// use soroban_sdk::{Bytes, BytesN, Env};
890///
891/// let env = Env::default();
892/// let bytes = Bytes::from_slice(&env, &[0; 32]);
893/// let bytes: BytesN<32> = bytes.try_into().expect("bytes to have length 32");
894/// assert_eq!(bytes.len(), 32);
895/// ```
896#[derive(Clone)]
897#[repr(transparent)]
898pub struct BytesN<const N: usize>(Bytes);
899
900impl<const N: usize> Debug for BytesN<N> {
901    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
902        write!(f, "BytesN<{}>(", N)?;
903        let mut iter = self.iter();
904        if let Some(x) = iter.next() {
905            write!(f, "{:?}", x)?;
906        }
907        for x in iter {
908            write!(f, ", {:?}", x)?;
909        }
910        write!(f, ")")?;
911        Ok(())
912    }
913}
914
915impl<const N: usize> Eq for BytesN<N> {}
916
917impl<const N: usize> PartialEq for BytesN<N> {
918    fn eq(&self, other: &Self) -> bool {
919        self.partial_cmp(other) == Some(Ordering::Equal)
920    }
921}
922
923impl<const N: usize> PartialEq<[u8; N]> for BytesN<N> {
924    fn eq(&self, other: &[u8; N]) -> bool {
925        let other: BytesN<N> = other.into_val(self.env());
926        self.eq(&other)
927    }
928}
929
930impl<const N: usize> PartialEq<BytesN<N>> for [u8; N] {
931    fn eq(&self, other: &BytesN<N>) -> bool {
932        let self_: BytesN<N> = self.into_val(other.env());
933        self_.eq(other)
934    }
935}
936
937impl<const N: usize> PartialOrd for BytesN<N> {
938    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
939        Some(Ord::cmp(self, other))
940    }
941}
942
943impl<const N: usize> PartialOrd<[u8; N]> for BytesN<N> {
944    fn partial_cmp(&self, other: &[u8; N]) -> Option<Ordering> {
945        let other: BytesN<N> = other.into_val(self.env());
946        self.partial_cmp(&other)
947    }
948}
949
950impl<const N: usize> PartialOrd<BytesN<N>> for [u8; N] {
951    fn partial_cmp(&self, other: &BytesN<N>) -> Option<Ordering> {
952        let self_: BytesN<N> = self.into_val(other.env());
953        self_.partial_cmp(other)
954    }
955}
956
957impl<const N: usize> Ord for BytesN<N> {
958    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
959        self.0.cmp(&other.0)
960    }
961}
962
963impl<const N: usize> Borrow<Bytes> for BytesN<N> {
964    fn borrow(&self) -> &Bytes {
965        &self.0
966    }
967}
968
969impl<const N: usize> Borrow<Bytes> for &BytesN<N> {
970    fn borrow(&self) -> &Bytes {
971        &self.0
972    }
973}
974
975impl<const N: usize> Borrow<Bytes> for &mut BytesN<N> {
976    fn borrow(&self) -> &Bytes {
977        &self.0
978    }
979}
980
981impl<const N: usize> AsRef<Bytes> for BytesN<N> {
982    fn as_ref(&self) -> &Bytes {
983        &self.0
984    }
985}
986
987impl<const N: usize> TryFromVal<Env, BytesN<N>> for BytesN<N> {
988    type Error = ConversionError;
989
990    fn try_from_val(_env: &Env, v: &BytesN<N>) -> Result<Self, Self::Error> {
991        Ok(v.clone())
992    }
993}
994
995impl<const N: usize> TryFromVal<Env, BytesN<N>> for Bytes {
996    type Error = ConversionError;
997
998    fn try_from_val(_env: &Env, v: &BytesN<N>) -> Result<Self, Self::Error> {
999        Ok(v.0.clone())
1000    }
1001}
1002
1003impl<const N: usize> TryFromVal<Env, [u8; N]> for BytesN<N> {
1004    type Error = ConversionError;
1005
1006    fn try_from_val(env: &Env, v: &[u8; N]) -> Result<Self, Self::Error> {
1007        Ok(BytesN::from_array(env, v))
1008    }
1009}
1010
1011impl<const N: usize> TryFromVal<Env, BytesN<N>> for [u8; N] {
1012    type Error = ConversionError;
1013
1014    fn try_from_val(_env: &Env, v: &BytesN<N>) -> Result<Self, Self::Error> {
1015        Ok(v.to_array())
1016    }
1017}
1018
1019impl<const N: usize> TryFromVal<Env, BytesObject> for BytesN<N> {
1020    type Error = ConversionError;
1021
1022    fn try_from_val(env: &Env, obj: &BytesObject) -> Result<Self, Self::Error> {
1023        Bytes::try_from_val(env, obj).unwrap_infallible().try_into()
1024    }
1025}
1026
1027impl<const N: usize> TryFromVal<Env, Val> for BytesN<N> {
1028    type Error = ConversionError;
1029
1030    fn try_from_val(env: &Env, val: &Val) -> Result<Self, Self::Error> {
1031        Bytes::try_from_val(env, val)?.try_into()
1032    }
1033}
1034
1035impl<const N: usize> TryFromVal<Env, BytesN<N>> for Val {
1036    type Error = ConversionError;
1037
1038    fn try_from_val(_env: &Env, v: &BytesN<N>) -> Result<Self, Self::Error> {
1039        Ok(v.to_val())
1040    }
1041}
1042
1043impl<const N: usize> TryFromVal<Env, &BytesN<N>> for Val {
1044    type Error = ConversionError;
1045
1046    fn try_from_val(_env: &Env, v: &&BytesN<N>) -> Result<Self, Self::Error> {
1047        Ok(v.to_val())
1048    }
1049}
1050
1051impl<const N: usize> TryFrom<Bytes> for BytesN<N> {
1052    type Error = ConversionError;
1053
1054    #[inline(always)]
1055    fn try_from(bin: Bytes) -> Result<Self, Self::Error> {
1056        if bin.len() == { N as u32 } {
1057            Ok(Self(bin))
1058        } else {
1059            Err(ConversionError {})
1060        }
1061    }
1062}
1063
1064impl<const N: usize> TryFrom<&Bytes> for BytesN<N> {
1065    type Error = ConversionError;
1066
1067    #[inline(always)]
1068    fn try_from(bin: &Bytes) -> Result<Self, Self::Error> {
1069        bin.clone().try_into()
1070    }
1071}
1072
1073impl<const N: usize> From<BytesN<N>> for Val {
1074    #[inline(always)]
1075    fn from(v: BytesN<N>) -> Self {
1076        v.0.into()
1077    }
1078}
1079
1080impl<const N: usize> From<BytesN<N>> for Bytes {
1081    #[inline(always)]
1082    fn from(v: BytesN<N>) -> Self {
1083        v.0
1084    }
1085}
1086
1087impl<const N: usize> From<&BytesN<N>> for Bytes {
1088    #[inline(always)]
1089    fn from(v: &BytesN<N>) -> Self {
1090        v.0.clone()
1091    }
1092}
1093
1094#[cfg(not(target_family = "wasm"))]
1095impl<const N: usize> From<&BytesN<N>> for ScVal {
1096    fn from(v: &BytesN<N>) -> Self {
1097        // This conversion occurs only in test utilities, and theoretically all
1098        // values should convert to an ScVal because the Env won't let the host
1099        // type to exist otherwise, unwrapping. Even if there are edge cases
1100        // that don't, this is a trade off for a better test developer
1101        // experience.
1102        ScVal::try_from_val(&v.0.env, &v.0.obj.to_val()).unwrap()
1103    }
1104}
1105
1106#[cfg(not(target_family = "wasm"))]
1107impl<const N: usize> From<BytesN<N>> for ScVal {
1108    fn from(v: BytesN<N>) -> Self {
1109        (&v).into()
1110    }
1111}
1112
1113#[cfg(not(target_family = "wasm"))]
1114impl<const N: usize> TryFromVal<Env, ScVal> for BytesN<N> {
1115    type Error = ConversionError;
1116    fn try_from_val(env: &Env, val: &ScVal) -> Result<Self, Self::Error> {
1117        Bytes::try_from_val(env, val)?.try_into()
1118    }
1119}
1120
1121impl<const N: usize> BytesN<N> {
1122    #[inline(always)]
1123    pub(crate) unsafe fn unchecked_new(env: Env, obj: BytesObject) -> Self {
1124        Self(Bytes::unchecked_new(env, obj))
1125    }
1126
1127    pub fn env(&self) -> &Env {
1128        self.0.env()
1129    }
1130
1131    pub fn as_val(&self) -> &Val {
1132        self.0.as_val()
1133    }
1134
1135    pub fn to_val(&self) -> Val {
1136        self.0.to_val()
1137    }
1138
1139    pub fn as_object(&self) -> &BytesObject {
1140        self.0.as_object()
1141    }
1142
1143    pub fn to_object(&self) -> BytesObject {
1144        self.0.to_object()
1145    }
1146
1147    /// Create a BytesN from the slice.
1148    #[inline(always)]
1149    pub fn from_array(env: &Env, items: &[u8; N]) -> BytesN<N> {
1150        BytesN(Bytes::from_slice(env, items))
1151    }
1152
1153    /// Sets the byte at the position with new value.
1154    ///
1155    /// ### Panics
1156    ///
1157    /// If the position is out-of-bounds.
1158    #[inline(always)]
1159    pub fn set(&mut self, i: u32, v: u8) {
1160        self.0.set(i, v);
1161    }
1162
1163    /// Returns the byte at the position or None if out-of-bounds.
1164    #[inline(always)]
1165    pub fn get(&self, i: u32) -> Option<u8> {
1166        self.0.get(i)
1167    }
1168
1169    /// Returns the byte at the position.
1170    ///
1171    /// ### Panics
1172    ///
1173    /// If the position is out-of-bounds.
1174    #[inline(always)]
1175    pub fn get_unchecked(&self, i: u32) -> u8 {
1176        self.0.get_unchecked(i)
1177    }
1178
1179    /// Returns true if the Bytes is empty and has a length of zero.
1180    #[inline(always)]
1181    pub fn is_empty(&self) -> bool {
1182        false
1183    }
1184
1185    /// Returns the number of bytes are in the Bytes.
1186    #[inline(always)]
1187    pub fn len(&self) -> u32 {
1188        N as u32
1189    }
1190
1191    /// Returns the first byte or None if empty.
1192    #[inline(always)]
1193    pub fn first(&self) -> Option<u8> {
1194        self.0.first()
1195    }
1196
1197    /// Returns the first byte.
1198    ///
1199    /// ### Panics
1200    ///
1201    /// If the Bytes is empty.
1202    #[inline(always)]
1203    pub fn first_unchecked(&self) -> u8 {
1204        self.0.first_unchecked()
1205    }
1206
1207    /// Returns the last byte or None if empty.
1208    #[inline(always)]
1209    pub fn last(&self) -> Option<u8> {
1210        self.0.last()
1211    }
1212
1213    /// Returns the last byte.
1214    ///
1215    /// ### Panics
1216    ///
1217    /// If the Bytes is empty.
1218    #[inline(always)]
1219    pub fn last_unchecked(&self) -> u8 {
1220        self.0.last_unchecked()
1221    }
1222
1223    /// Copy the bytes into the given slice.
1224    #[inline(always)]
1225    pub fn copy_into_slice(&self, slice: &mut [u8; N]) {
1226        let env = self.env();
1227        env.bytes_copy_to_slice(self.to_object(), Val::U32_ZERO, slice)
1228            .unwrap_optimized();
1229    }
1230
1231    /// Copy the bytes in [BytesN] into an array.
1232    #[inline(always)]
1233    pub fn to_array(&self) -> [u8; N] {
1234        let mut array = [0u8; N];
1235        self.copy_into_slice(&mut array);
1236        array
1237    }
1238
1239    pub fn iter(&self) -> BytesIter {
1240        self.clone().into_iter()
1241    }
1242}
1243
1244#[cfg(any(test, feature = "testutils"))]
1245#[cfg_attr(feature = "docs", doc(cfg(feature = "testutils")))]
1246impl<const N: usize> crate::testutils::BytesN<N> for BytesN<N> {
1247    fn random(env: &Env) -> BytesN<N> {
1248        BytesN::from_array(env, &crate::testutils::random())
1249    }
1250}
1251
1252impl<const N: usize> IntoIterator for BytesN<N> {
1253    type Item = u8;
1254
1255    type IntoIter = BytesIter;
1256
1257    fn into_iter(self) -> Self::IntoIter {
1258        BytesIter(self.0)
1259    }
1260}
1261
1262impl<const N: usize> TryFrom<Bytes> for [u8; N] {
1263    type Error = ConversionError;
1264
1265    fn try_from(bin: Bytes) -> Result<Self, Self::Error> {
1266        let fixed: BytesN<N> = bin.try_into()?;
1267        Ok(fixed.into())
1268    }
1269}
1270
1271impl<const N: usize> TryFrom<&Bytes> for [u8; N] {
1272    type Error = ConversionError;
1273
1274    fn try_from(bin: &Bytes) -> Result<Self, Self::Error> {
1275        let fixed: BytesN<N> = bin.try_into()?;
1276        Ok(fixed.into())
1277    }
1278}
1279
1280impl<const N: usize> From<BytesN<N>> for [u8; N] {
1281    fn from(bin: BytesN<N>) -> Self {
1282        let mut res = [0u8; N];
1283        for (i, b) in bin.into_iter().enumerate() {
1284            res[i] = b;
1285        }
1286        res
1287    }
1288}
1289
1290impl<const N: usize> From<&BytesN<N>> for [u8; N] {
1291    fn from(bin: &BytesN<N>) -> Self {
1292        let mut res = [0u8; N];
1293        for (i, b) in bin.iter().enumerate() {
1294            res[i] = b;
1295        }
1296        res
1297    }
1298}
1299
1300#[cfg(test)]
1301mod test {
1302    use super::*;
1303
1304    #[test]
1305    fn bytes_from_and_to_slices() {
1306        let env = Env::default();
1307
1308        let b = Bytes::from_slice(&env, &[1, 2, 3, 4]);
1309        let mut out = [0u8; 4];
1310        b.copy_into_slice(&mut out);
1311        assert_eq!([1, 2, 3, 4], out);
1312
1313        let mut b = Bytes::from_slice(&env, &[1, 2, 3, 4]);
1314        b.extend_from_slice(&[5, 6, 7, 8]);
1315        b.insert_from_slice(1, &[9, 10]);
1316        b.insert_from_bytes(4, Bytes::from_slice(&env, &[0, 0]));
1317        let mut out = [0u8; 12];
1318        b.copy_into_slice(&mut out);
1319        assert_eq!([1, 9, 10, 2, 0, 0, 3, 4, 5, 6, 7, 8], out);
1320        b.copy_from_slice(3, &[7, 6, 5]);
1321        b.copy_into_slice(&mut out);
1322        assert_eq!([1, 9, 10, 7, 6, 5, 3, 4, 5, 6, 7, 8], out);
1323    }
1324
1325    #[test]
1326    fn bytesn_from_and_to_slices() {
1327        let env = Env::default();
1328
1329        let b = BytesN::from_array(&env, &[1, 2, 3, 4]);
1330        let mut out = [0u8; 4];
1331        b.copy_into_slice(&mut out);
1332        assert_eq!([1, 2, 3, 4], out);
1333    }
1334
1335    #[test]
1336    #[should_panic]
1337    fn bytes_to_short_slice() {
1338        let env = Env::default();
1339        let b = Bytes::from_slice(&env, &[1, 2, 3, 4]);
1340        let mut out = [0u8; 3];
1341        b.copy_into_slice(&mut out);
1342    }
1343
1344    #[test]
1345    #[should_panic]
1346    fn bytes_to_long_slice() {
1347        let env = Env::default();
1348        let b = Bytes::from_slice(&env, &[1, 2, 3, 4]);
1349        let mut out = [0u8; 5];
1350        b.copy_into_slice(&mut out);
1351    }
1352
1353    #[test]
1354    fn macro_bytes() {
1355        let env = Env::default();
1356        assert_eq!(bytes!(&env), Bytes::new(&env));
1357        assert_eq!(bytes!(&env, 1), {
1358            let mut b = Bytes::new(&env);
1359            b.push_back(1);
1360            b
1361        });
1362        assert_eq!(bytes!(&env, 1,), {
1363            let mut b = Bytes::new(&env);
1364            b.push_back(1);
1365            b
1366        });
1367        assert_eq!(bytes!(&env, [3, 2, 1,]), {
1368            let mut b = Bytes::new(&env);
1369            b.push_back(3);
1370            b.push_back(2);
1371            b.push_back(1);
1372            b
1373        });
1374    }
1375
1376    #[test]
1377    fn macro_bytes_hex() {
1378        let env = Env::default();
1379        assert_eq!(bytes!(&env), Bytes::new(&env));
1380        assert_eq!(bytes!(&env, 1), {
1381            let mut b = Bytes::new(&env);
1382            b.push_back(1);
1383            b
1384        });
1385        assert_eq!(bytes!(&env, 1,), {
1386            let mut b = Bytes::new(&env);
1387            b.push_back(1);
1388            b
1389        });
1390        assert_eq!(bytes!(&env, 0x30201), {
1391            let mut b = Bytes::new(&env);
1392            b.push_back(3);
1393            b.push_back(2);
1394            b.push_back(1);
1395            b
1396        });
1397        assert_eq!(bytes!(&env, 0x0000030201), {
1398            Bytes::from_array(&env, &[0, 0, 3, 2, 1])
1399        });
1400    }
1401
1402    #[test]
1403    fn macro_bytesn() {
1404        let env = Env::default();
1405        assert_eq!(bytesn!(&env, 1), { BytesN::from_array(&env, &[1]) });
1406        assert_eq!(bytesn!(&env, 1,), { BytesN::from_array(&env, &[1]) });
1407        assert_eq!(bytesn!(&env, [3, 2, 1,]), {
1408            BytesN::from_array(&env, &[3, 2, 1])
1409        });
1410    }
1411
1412    #[test]
1413    fn macro_bytesn_hex() {
1414        let env = Env::default();
1415        assert_eq!(bytesn!(&env, 0x030201), {
1416            BytesN::from_array(&env, &[3, 2, 1])
1417        });
1418        assert_eq!(bytesn!(&env, 0x0000030201), {
1419            BytesN::from_array(&env, &[0, 0, 3, 2, 1])
1420        });
1421    }
1422
1423    #[test]
1424    fn test_bin() {
1425        let env = Env::default();
1426
1427        let mut bin = Bytes::new(&env);
1428        assert_eq!(bin.len(), 0);
1429        bin.push_back(10);
1430        assert_eq!(bin.len(), 1);
1431        bin.push_back(20);
1432        assert_eq!(bin.len(), 2);
1433        bin.push_back(30);
1434        assert_eq!(bin.len(), 3);
1435        println!("{:?}", bin);
1436
1437        let bin_ref = &bin;
1438        assert_eq!(bin_ref.len(), 3);
1439
1440        let mut bin_copy = bin.clone();
1441        assert!(bin == bin_copy);
1442        assert_eq!(bin_copy.len(), 3);
1443        bin_copy.push_back(40);
1444        assert_eq!(bin_copy.len(), 4);
1445        assert!(bin != bin_copy);
1446
1447        assert_eq!(bin.len(), 3);
1448        assert_eq!(bin_ref.len(), 3);
1449
1450        bin_copy.pop_back();
1451        assert!(bin == bin_copy);
1452
1453        let bad_fixed: Result<BytesN<4>, ConversionError> = bin.try_into();
1454        assert!(bad_fixed.is_err());
1455        let fixed: BytesN<3> = bin_copy.try_into().unwrap();
1456        println!("{:?}", fixed);
1457    }
1458
1459    #[test]
1460    fn test_bin_iter() {
1461        let env = Env::default();
1462        let mut bin = Bytes::new(&env);
1463        bin.push_back(10);
1464        bin.push_back(20);
1465        bin.push_back(30);
1466        let mut iter = bin.iter();
1467        assert_eq!(iter.next(), Some(10));
1468        assert_eq!(iter.next(), Some(20));
1469        assert_eq!(iter.next(), Some(30));
1470        assert_eq!(iter.next(), None);
1471        assert_eq!(iter.next(), None);
1472        let mut iter = bin.iter();
1473        assert_eq!(iter.next(), Some(10));
1474        assert_eq!(iter.next_back(), Some(30));
1475        assert_eq!(iter.next_back(), Some(20));
1476        assert_eq!(iter.next_back(), None);
1477        assert_eq!(iter.next_back(), None);
1478
1479        let fixed: BytesN<3> = bin.try_into().unwrap();
1480        let mut iter = fixed.iter();
1481        assert_eq!(iter.next(), Some(10));
1482        assert_eq!(iter.next(), Some(20));
1483        assert_eq!(iter.next(), Some(30));
1484        assert_eq!(iter.next(), None);
1485        assert_eq!(iter.next(), None);
1486        let mut iter = fixed.iter();
1487        assert_eq!(iter.next(), Some(10));
1488        assert_eq!(iter.next_back(), Some(30));
1489        assert_eq!(iter.next_back(), Some(20));
1490        assert_eq!(iter.next_back(), None);
1491        assert_eq!(iter.next_back(), None);
1492    }
1493
1494    #[test]
1495    fn test_array_binary_borrow() {
1496        fn get_len(b: impl Borrow<Bytes>) -> u32 {
1497            let b: &Bytes = b.borrow();
1498            b.len()
1499        }
1500
1501        let env = Env::default();
1502        let mut bin = Bytes::new(&env);
1503        bin.push_back(10);
1504        bin.push_back(20);
1505        bin.push_back(30);
1506        assert_eq!(bin.len(), 3);
1507
1508        let arr_bin: BytesN<3> = bin.clone().try_into().unwrap();
1509        assert_eq!(arr_bin.len(), 3);
1510
1511        assert_eq!(get_len(&bin), 3);
1512        assert_eq!(get_len(bin), 3);
1513        assert_eq!(get_len(&arr_bin), 3);
1514        assert_eq!(get_len(arr_bin), 3);
1515    }
1516
1517    #[test]
1518    fn bytesn_debug() {
1519        let env = Env::default();
1520        let mut bin = Bytes::new(&env);
1521        bin.push_back(10);
1522        bin.push_back(20);
1523        bin.push_back(30);
1524        let arr_bin: BytesN<3> = bin.clone().try_into().unwrap();
1525        assert_eq!(format!("{:?}", arr_bin), "BytesN<3>(10, 20, 30)");
1526    }
1527
1528    #[test]
1529    fn test_is_empty() {
1530        let env = Env::default();
1531        let mut bin = Bytes::new(&env);
1532        assert_eq!(bin.is_empty(), true);
1533        bin.push_back(10);
1534        assert_eq!(bin.is_empty(), false);
1535    }
1536
1537    #[test]
1538    fn test_first() {
1539        let env = Env::default();
1540        let mut bin = bytes![&env, [1, 2, 3, 4]];
1541
1542        assert_eq!(bin.first(), Some(1));
1543        bin.remove(0);
1544        assert_eq!(bin.first(), Some(2));
1545
1546        // first on empty bytes
1547        let bin = bytes![&env];
1548        assert_eq!(bin.first(), None);
1549    }
1550
1551    #[test]
1552    fn test_first_unchecked() {
1553        let env = Env::default();
1554        let mut bin = bytes![&env, [1, 2, 3, 4]];
1555
1556        assert_eq!(bin.first_unchecked(), 1);
1557        bin.remove(0);
1558        assert_eq!(bin.first_unchecked(), 2);
1559    }
1560
1561    #[test]
1562    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1563    fn test_first_unchecked_panics() {
1564        let env = Env::default();
1565        let bin = bytes![&env];
1566        bin.first_unchecked();
1567    }
1568
1569    #[test]
1570    fn test_last() {
1571        let env = Env::default();
1572        let mut bin = bytes![&env, [1, 2, 3, 4]];
1573
1574        assert_eq!(bin.last(), Some(4));
1575        bin.remove(3);
1576        assert_eq!(bin.last(), Some(3));
1577
1578        // last on empty bytes
1579        let bin = bytes![&env];
1580        assert_eq!(bin.last(), None);
1581    }
1582
1583    #[test]
1584    fn test_last_unchecked() {
1585        let env = Env::default();
1586        let mut bin = bytes![&env, [1, 2, 3, 4]];
1587
1588        assert_eq!(bin.last_unchecked(), 4);
1589        bin.remove(3);
1590        assert_eq!(bin.last_unchecked(), 3);
1591    }
1592
1593    #[test]
1594    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1595    fn test_last_unchecked_panics() {
1596        let env = Env::default();
1597        let bin = bytes![&env];
1598        bin.last_unchecked();
1599    }
1600
1601    #[test]
1602    fn test_get() {
1603        let env = Env::default();
1604        let bin = bytes![&env, [0, 1, 5, 2, 8]];
1605
1606        assert_eq!(bin.get(0), Some(0));
1607        assert_eq!(bin.get(1), Some(1));
1608        assert_eq!(bin.get(2), Some(5));
1609        assert_eq!(bin.get(3), Some(2));
1610        assert_eq!(bin.get(4), Some(8));
1611
1612        assert_eq!(bin.get(bin.len()), None);
1613        assert_eq!(bin.get(bin.len() + 1), None);
1614        assert_eq!(bin.get(u32::MAX), None);
1615
1616        // tests on an empty vec
1617        let bin = bytes![&env];
1618        assert_eq!(bin.get(0), None);
1619        assert_eq!(bin.get(bin.len()), None);
1620        assert_eq!(bin.get(bin.len() + 1), None);
1621        assert_eq!(bin.get(u32::MAX), None);
1622    }
1623
1624    #[test]
1625    fn test_get_unchecked() {
1626        let env = Env::default();
1627        let bin = bytes![&env, [0, 1, 5, 2, 8]];
1628
1629        assert_eq!(bin.get_unchecked(0), 0);
1630        assert_eq!(bin.get_unchecked(1), 1);
1631        assert_eq!(bin.get_unchecked(2), 5);
1632        assert_eq!(bin.get_unchecked(3), 2);
1633        assert_eq!(bin.get_unchecked(4), 8);
1634    }
1635
1636    #[test]
1637    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1638    fn test_get_unchecked_panics() {
1639        let env = Env::default();
1640        let bin = bytes![&env];
1641        bin.get_unchecked(0);
1642    }
1643
1644    #[test]
1645    fn test_remove() {
1646        let env = Env::default();
1647        let mut bin = bytes![&env, [1, 2, 3, 4]];
1648
1649        assert_eq!(bin.remove(2), Some(()));
1650        assert_eq!(bin, bytes![&env, [1, 2, 4]]);
1651        assert_eq!(bin.len(), 3);
1652
1653        // out of bound removes
1654        assert_eq!(bin.remove(bin.len()), None);
1655        assert_eq!(bin.remove(bin.len() + 1), None);
1656        assert_eq!(bin.remove(u32::MAX), None);
1657
1658        // remove rest of items
1659        assert_eq!(bin.remove(0), Some(()));
1660        assert_eq!(bin.remove(0), Some(()));
1661        assert_eq!(bin.remove(0), Some(()));
1662        assert_eq!(bin, bytes![&env]);
1663        assert_eq!(bin.len(), 0);
1664
1665        // try remove from empty bytes
1666        let mut bin = bytes![&env];
1667        assert_eq!(bin.remove(0), None);
1668        assert_eq!(bin.remove(bin.len()), None);
1669        assert_eq!(bin.remove(bin.len() + 1), None);
1670        assert_eq!(bin.remove(u32::MAX), None);
1671    }
1672
1673    #[test]
1674    fn test_remove_unchecked() {
1675        let env = Env::default();
1676        let mut bin = bytes![&env, [1, 2, 3, 4]];
1677
1678        bin.remove_unchecked(2);
1679        assert_eq!(bin, bytes![&env, [1, 2, 4]]);
1680        assert_eq!(bin.len(), 3);
1681    }
1682
1683    #[test]
1684    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1685    fn test_remove_unchecked_panics() {
1686        let env = Env::default();
1687        let mut bin = bytes![&env, [1, 2, 3, 4]];
1688        bin.remove_unchecked(bin.len());
1689    }
1690
1691    #[test]
1692    fn test_pop() {
1693        let env = Env::default();
1694        let mut bin = bytes![&env, [0, 1, 2, 3, 4]];
1695
1696        assert_eq!(bin.pop_back(), Some(4));
1697        assert_eq!(bin.pop_back(), Some(3));
1698        assert_eq!(bin.len(), 3);
1699        assert_eq!(bin, bytes![&env, [0, 1, 2]]);
1700
1701        // pop on empty bytes
1702        let mut bin = bytes![&env];
1703        assert_eq!(bin.pop_back(), None);
1704    }
1705
1706    #[test]
1707    fn test_pop_unchecked() {
1708        let env = Env::default();
1709        let mut bin = bytes![&env, [0, 1, 2, 3, 4]];
1710
1711        assert_eq!(bin.pop_back_unchecked(), 4);
1712        assert_eq!(bin.pop_back_unchecked(), 3);
1713        assert_eq!(bin.len(), 3);
1714        assert_eq!(bin, bytes![&env, [0, 1, 2]]);
1715    }
1716
1717    #[test]
1718    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1719    fn test_pop_unchecked_panics() {
1720        let env = Env::default();
1721        let mut bin = bytes![&env];
1722        bin.pop_back_unchecked();
1723    }
1724
1725    #[test]
1726    fn test_insert() {
1727        let env = Env::default();
1728        let mut bin = bytes![&env, [0, 1, 2, 3, 4]];
1729
1730        bin.insert(3, 42);
1731        assert_eq!(bin, bytes![&env, [0, 1, 2, 42, 3, 4]]);
1732
1733        // insert at start
1734        bin.insert(0, 43);
1735        assert_eq!(bin, bytes![&env, [43, 0, 1, 2, 42, 3, 4]]);
1736
1737        // insert at end
1738        bin.insert(bin.len(), 44);
1739        assert_eq!(bin, bytes![&env, [43, 0, 1, 2, 42, 3, 4, 44]]);
1740    }
1741
1742    #[test]
1743    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1744    fn test_insert_panic() {
1745        let env = Env::default();
1746        let mut bin = bytes![&env, [0, 1, 2, 3, 4]];
1747        bin.insert(80, 44);
1748    }
1749
1750    #[test]
1751    fn test_slice() {
1752        let env = Env::default();
1753        let bin = bytes![&env, [0, 1, 2, 3, 4]];
1754
1755        let bin2 = bin.slice(2..);
1756        assert_eq!(bin2, bytes![&env, [2, 3, 4]]);
1757
1758        let bin3 = bin.slice(3..3);
1759        assert_eq!(bin3, bytes![&env]);
1760
1761        let bin4 = bin.slice(0..3);
1762        assert_eq!(bin4, bytes![&env, [0, 1, 2]]);
1763
1764        let bin4 = bin.slice(3..5);
1765        assert_eq!(bin4, bytes![&env, [3, 4]]);
1766
1767        assert_eq!(bin, bytes![&env, [0, 1, 2, 3, 4]]); // makes sure original bytes is unchanged
1768    }
1769
1770    #[test]
1771    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1772    fn test_slice_panic() {
1773        let env = Env::default();
1774        let bin = bytes![&env, [0, 1, 2, 3, 4]];
1775        let _ = bin.slice(..=bin.len());
1776    }
1777}