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