Skip to main content

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