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