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