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