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