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#[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
743                .checked_add(1)
744                .expect_optimized("attempt to add with overflow"),
745            Bound::Unbounded => 0,
746        };
747        let end_bound = match r.end_bound() {
748            Bound::Included(s) => s
749                .checked_add(1)
750                .expect_optimized("attempt to add with overflow"),
751            Bound::Excluded(s) => *s,
752            Bound::Unbounded => self.len(),
753        };
754        let env = self.env();
755        let bin = env
756            .bytes_slice(self.obj, start_bound.into(), end_bound.into())
757            .unwrap_infallible();
758        unsafe { Self::unchecked_new(env.clone(), bin) }
759    }
760
761    pub fn iter(&self) -> BytesIter {
762        self.clone().into_iter()
763    }
764
765    /// Copy the bytes into a buffer of given size.
766    ///
767    /// Returns the buffer and a range of where the bytes live in the given
768    /// buffer.
769    ///
770    /// Suitable when the size of the bytes isn't a fixed size but it is known
771    /// to be under a certain size, or failure due to overflow is acceptable.
772    ///
773    /// ### Panics
774    ///
775    /// If the size of the bytes is larger than the size of the buffer. To avoid
776    /// this, first slice the bytes into a smaller size then convert to a
777    /// buffer.
778    #[must_use]
779    pub fn to_buffer<const B: usize>(&self) -> BytesBuffer<B> {
780        let mut buffer = [0u8; B];
781        let len = self.len() as usize;
782        {
783            let slice = &mut buffer[0..len];
784            self.copy_into_slice(slice);
785        }
786        BytesBuffer { buffer, len }
787    }
788
789    /// Copy the bytes into a Rust alloc Vec of size matching the bytes.
790    ///
791    /// Returns the Vec. Allocates using the built-in allocator.
792    ///
793    /// Suitable when the size of the bytes isn't a fixed size and the allocator
794    /// functionality of the sdk is enabled.
795    #[cfg(feature = "alloc")]
796    #[must_use]
797    pub fn to_alloc_vec(&self) -> alloc::vec::Vec<u8> {
798        let len = self.len() as usize;
799        let mut vec = alloc::vec::from_elem(0u8, len);
800        self.copy_into_slice(&mut vec);
801        vec
802    }
803
804    /// Converts the contents of the Bytes into a respective String object.
805    ///
806    /// The conversion doesn't try to interpret the bytes as any particular
807    /// encoding, as the SDK `String` type doesn't assume any encoding either.
808    pub fn to_string(&self) -> String {
809        self.into()
810    }
811}
812
813/// A `BytesBuffer` stores a variable number of bytes, up to a fixed limit `B`.
814///
815/// The bytes are stored in a fixed-size non-heap-allocated structure. It is a
816/// minimal wrapper around a fixed-size `[u8;B]` byte array and a length field
817/// indicating the amount of the byte array containing meaningful data.
818#[derive(Debug, Clone, PartialEq, Eq)]
819pub struct BytesBuffer<const B: usize> {
820    buffer: [u8; B],
821    len: usize,
822}
823
824impl<const B: usize> Borrow<[u8]> for BytesBuffer<B> {
825    /// Returns a borrow slice of the bytes stored in the BytesBuffer.
826    fn borrow(&self) -> &[u8] {
827        self.as_slice()
828    }
829}
830
831impl<const B: usize> BytesBuffer<B> {
832    /// Returns a borrow slice of the bytes stored in the BytesBuffer.
833    pub fn as_slice(&self) -> &[u8] {
834        &self.buffer[..self.len]
835    }
836}
837
838impl IntoIterator for Bytes {
839    type Item = u8;
840    type IntoIter = BytesIter;
841
842    fn into_iter(self) -> Self::IntoIter {
843        BytesIter(self)
844    }
845}
846
847#[derive(Clone)]
848pub struct BytesIter(Bytes);
849
850impl BytesIter {
851    fn into_bin(self) -> Bytes {
852        self.0
853    }
854}
855
856impl Iterator for BytesIter {
857    type Item = u8;
858
859    fn next(&mut self) -> Option<Self::Item> {
860        if self.0.is_empty() {
861            None
862        } else {
863            let val: u32 = self
864                .0
865                .env()
866                .bytes_front(self.0.obj)
867                .unwrap_infallible()
868                .into();
869            self.0 = self.0.slice(1..);
870            Some(val as u8)
871        }
872    }
873
874    fn size_hint(&self) -> (usize, Option<usize>) {
875        let len = self.0.len() as usize;
876        (len, Some(len))
877    }
878}
879
880impl DoubleEndedIterator for BytesIter {
881    fn next_back(&mut self) -> Option<Self::Item> {
882        let len = self.0.len();
883        if len == 0 {
884            None
885        } else {
886            let val: u32 = self
887                .0
888                .env()
889                .bytes_back(self.0.obj)
890                .unwrap_infallible()
891                .into();
892            self.0 = self.0.slice(..len - 1);
893            Some(val as u8)
894        }
895    }
896}
897
898impl FusedIterator for BytesIter {}
899
900impl ExactSizeIterator for BytesIter {
901    fn len(&self) -> usize {
902        self.0.len() as usize
903    }
904}
905
906/// BytesN is a contiguous fixed-size array type containing `u8`s.
907///
908/// The array is stored in the Host and available to the Guest through the
909/// functions defined on Bytes.
910///
911/// Bytes values can be stored as [Storage], or in other types like [Vec], [Map],
912/// etc.
913///
914/// ### Examples
915///
916/// BytesN values can be created from arrays:
917/// ```
918/// use soroban_sdk::{Bytes, BytesN, Env};
919///
920/// let env = Env::default();
921/// let bytes = BytesN::from_array(&env, &[0; 32]);
922/// assert_eq!(bytes.len(), 32);
923/// ```
924///
925/// BytesN and Bytes values are convertible:
926/// ```
927/// use soroban_sdk::{Bytes, BytesN, Env};
928///
929/// let env = Env::default();
930/// let bytes = Bytes::from_slice(&env, &[0; 32]);
931/// let bytes: BytesN<32> = bytes.try_into().expect("bytes to have length 32");
932/// assert_eq!(bytes.len(), 32);
933/// ```
934#[derive(Clone)]
935#[repr(transparent)]
936pub struct BytesN<const N: usize>(Bytes);
937
938impl<const N: usize> Debug for BytesN<N> {
939    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
940        write!(f, "BytesN<{}>(", N)?;
941        let mut iter = self.iter();
942        if let Some(x) = iter.next() {
943            write!(f, "{:?}", x)?;
944        }
945        for x in iter {
946            write!(f, ", {:?}", x)?;
947        }
948        write!(f, ")")?;
949        Ok(())
950    }
951}
952
953impl<const N: usize> Eq for BytesN<N> {}
954
955impl<const N: usize> PartialEq for BytesN<N> {
956    fn eq(&self, other: &Self) -> bool {
957        self.partial_cmp(other) == Some(Ordering::Equal)
958    }
959}
960
961impl<const N: usize> PartialEq<[u8; N]> for BytesN<N> {
962    fn eq(&self, other: &[u8; N]) -> bool {
963        let other: BytesN<N> = other.into_val(self.env());
964        self.eq(&other)
965    }
966}
967
968impl<const N: usize> PartialEq<BytesN<N>> for [u8; N] {
969    fn eq(&self, other: &BytesN<N>) -> bool {
970        let self_: BytesN<N> = self.into_val(other.env());
971        self_.eq(other)
972    }
973}
974
975impl<const N: usize> PartialOrd for BytesN<N> {
976    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
977        Some(Ord::cmp(self, other))
978    }
979}
980
981impl<const N: usize> PartialOrd<[u8; N]> for BytesN<N> {
982    fn partial_cmp(&self, other: &[u8; N]) -> Option<Ordering> {
983        let other: BytesN<N> = other.into_val(self.env());
984        self.partial_cmp(&other)
985    }
986}
987
988impl<const N: usize> PartialOrd<BytesN<N>> for [u8; N] {
989    fn partial_cmp(&self, other: &BytesN<N>) -> Option<Ordering> {
990        let self_: BytesN<N> = self.into_val(other.env());
991        self_.partial_cmp(other)
992    }
993}
994
995impl<const N: usize> Ord for BytesN<N> {
996    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
997        self.0.cmp(&other.0)
998    }
999}
1000
1001impl<const N: usize> Borrow<Bytes> for BytesN<N> {
1002    fn borrow(&self) -> &Bytes {
1003        &self.0
1004    }
1005}
1006
1007impl<const N: usize> Borrow<Bytes> for &BytesN<N> {
1008    fn borrow(&self) -> &Bytes {
1009        &self.0
1010    }
1011}
1012
1013impl<const N: usize> Borrow<Bytes> for &mut BytesN<N> {
1014    fn borrow(&self) -> &Bytes {
1015        &self.0
1016    }
1017}
1018
1019impl<const N: usize> AsRef<Bytes> for BytesN<N> {
1020    fn as_ref(&self) -> &Bytes {
1021        &self.0
1022    }
1023}
1024
1025impl<const N: usize> TryFromVal<Env, BytesN<N>> for BytesN<N> {
1026    type Error = ConversionError;
1027
1028    fn try_from_val(_env: &Env, v: &BytesN<N>) -> Result<Self, Self::Error> {
1029        Ok(v.clone())
1030    }
1031}
1032
1033impl<const N: usize> TryFromVal<Env, BytesN<N>> for Bytes {
1034    type Error = ConversionError;
1035
1036    fn try_from_val(_env: &Env, v: &BytesN<N>) -> Result<Self, Self::Error> {
1037        Ok(v.0.clone())
1038    }
1039}
1040
1041impl<const N: usize> TryFromVal<Env, [u8; N]> for BytesN<N> {
1042    type Error = ConversionError;
1043
1044    fn try_from_val(env: &Env, v: &[u8; N]) -> Result<Self, Self::Error> {
1045        Ok(BytesN::from_array(env, v))
1046    }
1047}
1048
1049impl<const N: usize> TryFromVal<Env, BytesN<N>> for [u8; N] {
1050    type Error = ConversionError;
1051
1052    fn try_from_val(_env: &Env, v: &BytesN<N>) -> Result<Self, Self::Error> {
1053        Ok(v.to_array())
1054    }
1055}
1056
1057impl<const N: usize> TryFromVal<Env, BytesObject> for BytesN<N> {
1058    type Error = ConversionError;
1059
1060    fn try_from_val(env: &Env, obj: &BytesObject) -> Result<Self, Self::Error> {
1061        Bytes::try_from_val(env, obj).unwrap_infallible().try_into()
1062    }
1063}
1064
1065impl<const N: usize> TryFromVal<Env, Val> for BytesN<N> {
1066    type Error = ConversionError;
1067
1068    fn try_from_val(env: &Env, val: &Val) -> Result<Self, Self::Error> {
1069        Bytes::try_from_val(env, val)?.try_into()
1070    }
1071}
1072
1073impl<const N: usize> TryFromVal<Env, BytesN<N>> for Val {
1074    type Error = ConversionError;
1075
1076    fn try_from_val(_env: &Env, v: &BytesN<N>) -> Result<Self, Self::Error> {
1077        Ok(v.to_val())
1078    }
1079}
1080
1081impl<const N: usize> TryFromVal<Env, &BytesN<N>> for Val {
1082    type Error = ConversionError;
1083
1084    fn try_from_val(_env: &Env, v: &&BytesN<N>) -> Result<Self, Self::Error> {
1085        Ok(v.to_val())
1086    }
1087}
1088
1089impl<const N: usize> TryFrom<Bytes> for BytesN<N> {
1090    type Error = ConversionError;
1091
1092    #[inline(always)]
1093    fn try_from(bin: Bytes) -> Result<Self, Self::Error> {
1094        if bin.len() == { N as u32 } {
1095            Ok(Self(bin))
1096        } else {
1097            Err(ConversionError {})
1098        }
1099    }
1100}
1101
1102impl<const N: usize> TryFrom<&Bytes> for BytesN<N> {
1103    type Error = ConversionError;
1104
1105    #[inline(always)]
1106    fn try_from(bin: &Bytes) -> Result<Self, Self::Error> {
1107        bin.clone().try_into()
1108    }
1109}
1110
1111impl<const N: usize> From<BytesN<N>> for Val {
1112    #[inline(always)]
1113    fn from(v: BytesN<N>) -> Self {
1114        v.0.into()
1115    }
1116}
1117
1118impl<const N: usize> From<BytesN<N>> for Bytes {
1119    #[inline(always)]
1120    fn from(v: BytesN<N>) -> Self {
1121        v.into_bytes()
1122    }
1123}
1124
1125impl<const N: usize> From<&BytesN<N>> for Bytes {
1126    #[inline(always)]
1127    fn from(v: &BytesN<N>) -> Self {
1128        v.to_bytes()
1129    }
1130}
1131
1132#[cfg(not(target_family = "wasm"))]
1133impl<const N: usize> From<&BytesN<N>> for ScVal {
1134    fn from(v: &BytesN<N>) -> Self {
1135        // This conversion occurs only in test utilities, and theoretically all
1136        // values should convert to an ScVal because the Env won't let the host
1137        // type to exist otherwise, unwrapping. Even if there are edge cases
1138        // that don't, this is a trade off for a better test developer
1139        // experience.
1140        ScVal::try_from_val(&v.0.env, &v.0.obj.to_val()).unwrap()
1141    }
1142}
1143
1144#[cfg(not(target_family = "wasm"))]
1145impl<const N: usize> From<BytesN<N>> for ScVal {
1146    fn from(v: BytesN<N>) -> Self {
1147        (&v).into()
1148    }
1149}
1150
1151#[cfg(not(target_family = "wasm"))]
1152impl<const N: usize> TryFromVal<Env, ScVal> for BytesN<N> {
1153    type Error = ConversionError;
1154    fn try_from_val(env: &Env, val: &ScVal) -> Result<Self, Self::Error> {
1155        Bytes::try_from_val(env, val)?.try_into()
1156    }
1157}
1158
1159impl<const N: usize> BytesN<N> {
1160    #[inline(always)]
1161    pub(crate) unsafe fn unchecked_new(env: Env, obj: BytesObject) -> Self {
1162        Self(Bytes::unchecked_new(env, obj))
1163    }
1164
1165    pub fn env(&self) -> &Env {
1166        self.0.env()
1167    }
1168
1169    pub fn as_bytes(&self) -> &Bytes {
1170        &self.0
1171    }
1172
1173    pub fn into_bytes(self) -> Bytes {
1174        self.0
1175    }
1176
1177    pub fn to_bytes(&self) -> Bytes {
1178        self.0.clone()
1179    }
1180
1181    pub fn as_val(&self) -> &Val {
1182        self.0.as_val()
1183    }
1184
1185    pub fn to_val(&self) -> Val {
1186        self.0.to_val()
1187    }
1188
1189    pub fn as_object(&self) -> &BytesObject {
1190        self.0.as_object()
1191    }
1192
1193    pub fn to_object(&self) -> BytesObject {
1194        self.0.to_object()
1195    }
1196
1197    /// Create a BytesN from the slice.
1198    #[inline(always)]
1199    pub fn from_array(env: &Env, items: &[u8; N]) -> BytesN<N> {
1200        BytesN(Bytes::from_slice(env, items))
1201    }
1202
1203    /// Sets the byte at the position with new value.
1204    ///
1205    /// ### Panics
1206    ///
1207    /// If the position is out-of-bounds.
1208    #[inline(always)]
1209    pub fn set(&mut self, i: u32, v: u8) {
1210        self.0.set(i, v);
1211    }
1212
1213    /// Returns the byte at the position or None if out-of-bounds.
1214    #[inline(always)]
1215    pub fn get(&self, i: u32) -> Option<u8> {
1216        self.0.get(i)
1217    }
1218
1219    /// Returns the byte at the position.
1220    ///
1221    /// ### Panics
1222    ///
1223    /// If the position is out-of-bounds.
1224    #[inline(always)]
1225    pub fn get_unchecked(&self, i: u32) -> u8 {
1226        self.0.get_unchecked(i)
1227    }
1228
1229    /// Returns true if the Bytes is empty and has a length of zero.
1230    #[inline(always)]
1231    pub fn is_empty(&self) -> bool {
1232        false
1233    }
1234
1235    /// Returns the number of bytes are in the Bytes.
1236    #[inline(always)]
1237    pub fn len(&self) -> u32 {
1238        N as u32
1239    }
1240
1241    /// Returns the first byte or None if empty.
1242    #[inline(always)]
1243    pub fn first(&self) -> Option<u8> {
1244        self.0.first()
1245    }
1246
1247    /// Returns the first byte.
1248    ///
1249    /// ### Panics
1250    ///
1251    /// If the Bytes is empty.
1252    #[inline(always)]
1253    pub fn first_unchecked(&self) -> u8 {
1254        self.0.first_unchecked()
1255    }
1256
1257    /// Returns the last byte or None if empty.
1258    #[inline(always)]
1259    pub fn last(&self) -> Option<u8> {
1260        self.0.last()
1261    }
1262
1263    /// Returns the last byte.
1264    ///
1265    /// ### Panics
1266    ///
1267    /// If the Bytes is empty.
1268    #[inline(always)]
1269    pub fn last_unchecked(&self) -> u8 {
1270        self.0.last_unchecked()
1271    }
1272
1273    /// Copy the bytes into the given slice.
1274    #[inline(always)]
1275    pub fn copy_into_slice(&self, slice: &mut [u8; N]) {
1276        let env = self.env();
1277        env.bytes_copy_to_slice(self.to_object(), Val::U32_ZERO, slice)
1278            .unwrap_optimized();
1279    }
1280
1281    /// Copy the bytes in [BytesN] into an array.
1282    #[inline(always)]
1283    pub fn to_array(&self) -> [u8; N] {
1284        let mut array = [0u8; N];
1285        self.copy_into_slice(&mut array);
1286        array
1287    }
1288
1289    pub fn iter(&self) -> BytesIter {
1290        self.clone().into_iter()
1291    }
1292}
1293
1294#[cfg(any(test, feature = "testutils"))]
1295#[cfg_attr(feature = "docs", doc(cfg(feature = "testutils")))]
1296impl<const N: usize> crate::testutils::BytesN<N> for BytesN<N> {
1297    fn random(env: &Env) -> BytesN<N> {
1298        BytesN::from_array(env, &crate::testutils::random())
1299    }
1300}
1301
1302impl<const N: usize> IntoIterator for BytesN<N> {
1303    type Item = u8;
1304
1305    type IntoIter = BytesIter;
1306
1307    fn into_iter(self) -> Self::IntoIter {
1308        BytesIter(self.0)
1309    }
1310}
1311
1312impl<const N: usize> TryFrom<Bytes> for [u8; N] {
1313    type Error = ConversionError;
1314
1315    fn try_from(bin: Bytes) -> Result<Self, Self::Error> {
1316        let fixed: BytesN<N> = bin.try_into()?;
1317        Ok(fixed.into())
1318    }
1319}
1320
1321impl<const N: usize> TryFrom<&Bytes> for [u8; N] {
1322    type Error = ConversionError;
1323
1324    fn try_from(bin: &Bytes) -> Result<Self, Self::Error> {
1325        let fixed: BytesN<N> = bin.try_into()?;
1326        Ok(fixed.into())
1327    }
1328}
1329
1330impl<const N: usize> From<BytesN<N>> for [u8; N] {
1331    fn from(bin: BytesN<N>) -> Self {
1332        let mut res = [0u8; N];
1333        for (i, b) in bin.into_iter().enumerate() {
1334            res[i] = b;
1335        }
1336        res
1337    }
1338}
1339
1340impl<const N: usize> From<&BytesN<N>> for [u8; N] {
1341    fn from(bin: &BytesN<N>) -> Self {
1342        let mut res = [0u8; N];
1343        for (i, b) in bin.iter().enumerate() {
1344            res[i] = b;
1345        }
1346        res
1347    }
1348}
1349
1350#[cfg(test)]
1351mod test {
1352    use super::*;
1353
1354    #[test]
1355    fn bytes_from_and_to_slices() {
1356        let env = Env::default();
1357
1358        let b = Bytes::from_slice(&env, &[1, 2, 3, 4]);
1359        let mut out = [0u8; 4];
1360        b.copy_into_slice(&mut out);
1361        assert_eq!([1, 2, 3, 4], out);
1362
1363        let mut b = Bytes::from_slice(&env, &[1, 2, 3, 4]);
1364        b.extend_from_slice(&[5, 6, 7, 8]);
1365        b.insert_from_slice(1, &[9, 10]);
1366        b.insert_from_bytes(4, Bytes::from_slice(&env, &[0, 0]));
1367        let mut out = [0u8; 12];
1368        b.copy_into_slice(&mut out);
1369        assert_eq!([1, 9, 10, 2, 0, 0, 3, 4, 5, 6, 7, 8], out);
1370        b.copy_from_slice(3, &[7, 6, 5]);
1371        b.copy_into_slice(&mut out);
1372        assert_eq!([1, 9, 10, 7, 6, 5, 3, 4, 5, 6, 7, 8], out);
1373    }
1374
1375    #[test]
1376    fn bytesn_from_and_to_slices() {
1377        let env = Env::default();
1378
1379        let b = BytesN::from_array(&env, &[1, 2, 3, 4]);
1380        let mut out = [0u8; 4];
1381        b.copy_into_slice(&mut out);
1382        assert_eq!([1, 2, 3, 4], out);
1383    }
1384
1385    #[test]
1386    #[should_panic]
1387    fn bytes_to_short_slice() {
1388        let env = Env::default();
1389        let b = Bytes::from_slice(&env, &[1, 2, 3, 4]);
1390        let mut out = [0u8; 3];
1391        b.copy_into_slice(&mut out);
1392    }
1393
1394    #[test]
1395    #[should_panic]
1396    fn bytes_to_long_slice() {
1397        let env = Env::default();
1398        let b = Bytes::from_slice(&env, &[1, 2, 3, 4]);
1399        let mut out = [0u8; 5];
1400        b.copy_into_slice(&mut out);
1401    }
1402
1403    #[test]
1404    fn macro_bytes() {
1405        let env = Env::default();
1406        assert_eq!(bytes!(&env), Bytes::new(&env));
1407        assert_eq!(bytes!(&env, 1), {
1408            let mut b = Bytes::new(&env);
1409            b.push_back(1);
1410            b
1411        });
1412        assert_eq!(bytes!(&env, 1,), {
1413            let mut b = Bytes::new(&env);
1414            b.push_back(1);
1415            b
1416        });
1417        assert_eq!(bytes!(&env, [3, 2, 1,]), {
1418            let mut b = Bytes::new(&env);
1419            b.push_back(3);
1420            b.push_back(2);
1421            b.push_back(1);
1422            b
1423        });
1424    }
1425
1426    #[test]
1427    fn macro_bytes_hex() {
1428        let env = Env::default();
1429        assert_eq!(bytes!(&env), Bytes::new(&env));
1430        assert_eq!(bytes!(&env, 1), {
1431            let mut b = Bytes::new(&env);
1432            b.push_back(1);
1433            b
1434        });
1435        assert_eq!(bytes!(&env, 1,), {
1436            let mut b = Bytes::new(&env);
1437            b.push_back(1);
1438            b
1439        });
1440        assert_eq!(bytes!(&env, 0x30201), {
1441            let mut b = Bytes::new(&env);
1442            b.push_back(3);
1443            b.push_back(2);
1444            b.push_back(1);
1445            b
1446        });
1447        assert_eq!(bytes!(&env, 0x0000030201), {
1448            Bytes::from_array(&env, &[0, 0, 3, 2, 1])
1449        });
1450    }
1451
1452    #[test]
1453    fn macro_bytesn() {
1454        let env = Env::default();
1455        assert_eq!(bytesn!(&env, 1), { BytesN::from_array(&env, &[1]) });
1456        assert_eq!(bytesn!(&env, 1,), { BytesN::from_array(&env, &[1]) });
1457        assert_eq!(bytesn!(&env, [3, 2, 1,]), {
1458            BytesN::from_array(&env, &[3, 2, 1])
1459        });
1460    }
1461
1462    #[test]
1463    fn macro_bytesn_hex() {
1464        let env = Env::default();
1465        assert_eq!(bytesn!(&env, 0x030201), {
1466            BytesN::from_array(&env, &[3, 2, 1])
1467        });
1468        assert_eq!(bytesn!(&env, 0x0000030201), {
1469            BytesN::from_array(&env, &[0, 0, 3, 2, 1])
1470        });
1471    }
1472
1473    #[test]
1474    fn test_bin() {
1475        let env = Env::default();
1476
1477        let mut bin = Bytes::new(&env);
1478        assert_eq!(bin.len(), 0);
1479        bin.push_back(10);
1480        assert_eq!(bin.len(), 1);
1481        bin.push_back(20);
1482        assert_eq!(bin.len(), 2);
1483        bin.push_back(30);
1484        assert_eq!(bin.len(), 3);
1485        println!("{:?}", bin);
1486
1487        let bin_ref = &bin;
1488        assert_eq!(bin_ref.len(), 3);
1489
1490        let mut bin_copy = bin.clone();
1491        assert!(bin == bin_copy);
1492        assert_eq!(bin_copy.len(), 3);
1493        bin_copy.push_back(40);
1494        assert_eq!(bin_copy.len(), 4);
1495        assert!(bin != bin_copy);
1496
1497        assert_eq!(bin.len(), 3);
1498        assert_eq!(bin_ref.len(), 3);
1499
1500        bin_copy.pop_back();
1501        assert!(bin == bin_copy);
1502
1503        let bad_fixed: Result<BytesN<4>, ConversionError> = bin.try_into();
1504        assert!(bad_fixed.is_err());
1505        let fixed: BytesN<3> = bin_copy.try_into().unwrap();
1506        println!("{:?}", fixed);
1507    }
1508
1509    #[test]
1510    fn test_bin_iter() {
1511        let env = Env::default();
1512        let mut bin = Bytes::new(&env);
1513        bin.push_back(10);
1514        bin.push_back(20);
1515        bin.push_back(30);
1516        let mut iter = bin.iter();
1517        assert_eq!(iter.next(), Some(10));
1518        assert_eq!(iter.next(), Some(20));
1519        assert_eq!(iter.next(), Some(30));
1520        assert_eq!(iter.next(), None);
1521        assert_eq!(iter.next(), None);
1522        let mut iter = bin.iter();
1523        assert_eq!(iter.next(), Some(10));
1524        assert_eq!(iter.next_back(), Some(30));
1525        assert_eq!(iter.next_back(), Some(20));
1526        assert_eq!(iter.next_back(), None);
1527        assert_eq!(iter.next_back(), None);
1528
1529        let fixed: BytesN<3> = bin.try_into().unwrap();
1530        let mut iter = fixed.iter();
1531        assert_eq!(iter.next(), Some(10));
1532        assert_eq!(iter.next(), Some(20));
1533        assert_eq!(iter.next(), Some(30));
1534        assert_eq!(iter.next(), None);
1535        assert_eq!(iter.next(), None);
1536        let mut iter = fixed.iter();
1537        assert_eq!(iter.next(), Some(10));
1538        assert_eq!(iter.next_back(), Some(30));
1539        assert_eq!(iter.next_back(), Some(20));
1540        assert_eq!(iter.next_back(), None);
1541        assert_eq!(iter.next_back(), None);
1542    }
1543
1544    #[test]
1545    fn test_array_binary_borrow() {
1546        fn get_len(b: impl Borrow<Bytes>) -> u32 {
1547            let b: &Bytes = b.borrow();
1548            b.len()
1549        }
1550
1551        let env = Env::default();
1552        let mut bin = Bytes::new(&env);
1553        bin.push_back(10);
1554        bin.push_back(20);
1555        bin.push_back(30);
1556        assert_eq!(bin.len(), 3);
1557
1558        let arr_bin: BytesN<3> = bin.clone().try_into().unwrap();
1559        assert_eq!(arr_bin.len(), 3);
1560
1561        assert_eq!(get_len(&bin), 3);
1562        assert_eq!(get_len(bin), 3);
1563        assert_eq!(get_len(&arr_bin), 3);
1564        assert_eq!(get_len(arr_bin), 3);
1565    }
1566
1567    #[test]
1568    fn bytesn_debug() {
1569        let env = Env::default();
1570        let mut bin = Bytes::new(&env);
1571        bin.push_back(10);
1572        bin.push_back(20);
1573        bin.push_back(30);
1574        let arr_bin: BytesN<3> = bin.clone().try_into().unwrap();
1575        assert_eq!(format!("{:?}", arr_bin), "BytesN<3>(10, 20, 30)");
1576    }
1577
1578    #[test]
1579    fn test_is_empty() {
1580        let env = Env::default();
1581        let mut bin = Bytes::new(&env);
1582        assert_eq!(bin.is_empty(), true);
1583        bin.push_back(10);
1584        assert_eq!(bin.is_empty(), false);
1585    }
1586
1587    #[test]
1588    fn test_first() {
1589        let env = Env::default();
1590        let mut bin = bytes![&env, [1, 2, 3, 4]];
1591
1592        assert_eq!(bin.first(), Some(1));
1593        bin.remove(0);
1594        assert_eq!(bin.first(), Some(2));
1595
1596        // first on empty bytes
1597        let bin = bytes![&env];
1598        assert_eq!(bin.first(), None);
1599    }
1600
1601    #[test]
1602    fn test_first_unchecked() {
1603        let env = Env::default();
1604        let mut bin = bytes![&env, [1, 2, 3, 4]];
1605
1606        assert_eq!(bin.first_unchecked(), 1);
1607        bin.remove(0);
1608        assert_eq!(bin.first_unchecked(), 2);
1609    }
1610
1611    #[test]
1612    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1613    fn test_first_unchecked_panics() {
1614        let env = Env::default();
1615        let bin = bytes![&env];
1616        bin.first_unchecked();
1617    }
1618
1619    #[test]
1620    fn test_last() {
1621        let env = Env::default();
1622        let mut bin = bytes![&env, [1, 2, 3, 4]];
1623
1624        assert_eq!(bin.last(), Some(4));
1625        bin.remove(3);
1626        assert_eq!(bin.last(), Some(3));
1627
1628        // last on empty bytes
1629        let bin = bytes![&env];
1630        assert_eq!(bin.last(), None);
1631    }
1632
1633    #[test]
1634    fn test_last_unchecked() {
1635        let env = Env::default();
1636        let mut bin = bytes![&env, [1, 2, 3, 4]];
1637
1638        assert_eq!(bin.last_unchecked(), 4);
1639        bin.remove(3);
1640        assert_eq!(bin.last_unchecked(), 3);
1641    }
1642
1643    #[test]
1644    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1645    fn test_last_unchecked_panics() {
1646        let env = Env::default();
1647        let bin = bytes![&env];
1648        bin.last_unchecked();
1649    }
1650
1651    #[test]
1652    fn test_get() {
1653        let env = Env::default();
1654        let bin = bytes![&env, [0, 1, 5, 2, 8]];
1655
1656        assert_eq!(bin.get(0), Some(0));
1657        assert_eq!(bin.get(1), Some(1));
1658        assert_eq!(bin.get(2), Some(5));
1659        assert_eq!(bin.get(3), Some(2));
1660        assert_eq!(bin.get(4), Some(8));
1661
1662        assert_eq!(bin.get(bin.len()), None);
1663        assert_eq!(bin.get(bin.len() + 1), None);
1664        assert_eq!(bin.get(u32::MAX), None);
1665
1666        // tests on an empty vec
1667        let bin = bytes![&env];
1668        assert_eq!(bin.get(0), None);
1669        assert_eq!(bin.get(bin.len()), None);
1670        assert_eq!(bin.get(bin.len() + 1), None);
1671        assert_eq!(bin.get(u32::MAX), None);
1672    }
1673
1674    #[test]
1675    fn test_get_unchecked() {
1676        let env = Env::default();
1677        let bin = bytes![&env, [0, 1, 5, 2, 8]];
1678
1679        assert_eq!(bin.get_unchecked(0), 0);
1680        assert_eq!(bin.get_unchecked(1), 1);
1681        assert_eq!(bin.get_unchecked(2), 5);
1682        assert_eq!(bin.get_unchecked(3), 2);
1683        assert_eq!(bin.get_unchecked(4), 8);
1684    }
1685
1686    #[test]
1687    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1688    fn test_get_unchecked_panics() {
1689        let env = Env::default();
1690        let bin = bytes![&env];
1691        bin.get_unchecked(0);
1692    }
1693
1694    #[test]
1695    fn test_remove() {
1696        let env = Env::default();
1697        let mut bin = bytes![&env, [1, 2, 3, 4]];
1698
1699        assert_eq!(bin.remove(2), Some(()));
1700        assert_eq!(bin, bytes![&env, [1, 2, 4]]);
1701        assert_eq!(bin.len(), 3);
1702
1703        // out of bound removes
1704        assert_eq!(bin.remove(bin.len()), None);
1705        assert_eq!(bin.remove(bin.len() + 1), None);
1706        assert_eq!(bin.remove(u32::MAX), None);
1707
1708        // remove rest of items
1709        assert_eq!(bin.remove(0), Some(()));
1710        assert_eq!(bin.remove(0), Some(()));
1711        assert_eq!(bin.remove(0), Some(()));
1712        assert_eq!(bin, bytes![&env]);
1713        assert_eq!(bin.len(), 0);
1714
1715        // try remove from empty bytes
1716        let mut bin = bytes![&env];
1717        assert_eq!(bin.remove(0), None);
1718        assert_eq!(bin.remove(bin.len()), None);
1719        assert_eq!(bin.remove(bin.len() + 1), None);
1720        assert_eq!(bin.remove(u32::MAX), None);
1721    }
1722
1723    #[test]
1724    fn test_remove_unchecked() {
1725        let env = Env::default();
1726        let mut bin = bytes![&env, [1, 2, 3, 4]];
1727
1728        bin.remove_unchecked(2);
1729        assert_eq!(bin, bytes![&env, [1, 2, 4]]);
1730        assert_eq!(bin.len(), 3);
1731    }
1732
1733    #[test]
1734    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1735    fn test_remove_unchecked_panics() {
1736        let env = Env::default();
1737        let mut bin = bytes![&env, [1, 2, 3, 4]];
1738        bin.remove_unchecked(bin.len());
1739    }
1740
1741    #[test]
1742    fn test_pop() {
1743        let env = Env::default();
1744        let mut bin = bytes![&env, [0, 1, 2, 3, 4]];
1745
1746        assert_eq!(bin.pop_back(), Some(4));
1747        assert_eq!(bin.pop_back(), Some(3));
1748        assert_eq!(bin.len(), 3);
1749        assert_eq!(bin, bytes![&env, [0, 1, 2]]);
1750
1751        // pop on empty bytes
1752        let mut bin = bytes![&env];
1753        assert_eq!(bin.pop_back(), None);
1754    }
1755
1756    #[test]
1757    fn test_pop_unchecked() {
1758        let env = Env::default();
1759        let mut bin = bytes![&env, [0, 1, 2, 3, 4]];
1760
1761        assert_eq!(bin.pop_back_unchecked(), 4);
1762        assert_eq!(bin.pop_back_unchecked(), 3);
1763        assert_eq!(bin.len(), 3);
1764        assert_eq!(bin, bytes![&env, [0, 1, 2]]);
1765    }
1766
1767    #[test]
1768    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1769    fn test_pop_unchecked_panics() {
1770        let env = Env::default();
1771        let mut bin = bytes![&env];
1772        bin.pop_back_unchecked();
1773    }
1774
1775    #[test]
1776    fn test_insert() {
1777        let env = Env::default();
1778        let mut bin = bytes![&env, [0, 1, 2, 3, 4]];
1779
1780        bin.insert(3, 42);
1781        assert_eq!(bin, bytes![&env, [0, 1, 2, 42, 3, 4]]);
1782
1783        // insert at start
1784        bin.insert(0, 43);
1785        assert_eq!(bin, bytes![&env, [43, 0, 1, 2, 42, 3, 4]]);
1786
1787        // insert at end
1788        bin.insert(bin.len(), 44);
1789        assert_eq!(bin, bytes![&env, [43, 0, 1, 2, 42, 3, 4, 44]]);
1790    }
1791
1792    #[test]
1793    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1794    fn test_insert_panic() {
1795        let env = Env::default();
1796        let mut bin = bytes![&env, [0, 1, 2, 3, 4]];
1797        bin.insert(80, 44);
1798    }
1799
1800    #[test]
1801    fn test_slice() {
1802        let env = Env::default();
1803        let bin = bytes![&env, [0, 1, 2, 3, 4]];
1804
1805        let bin2 = bin.slice(2..);
1806        assert_eq!(bin2, bytes![&env, [2, 3, 4]]);
1807
1808        let bin3 = bin.slice(3..3);
1809        assert_eq!(bin3, bytes![&env]);
1810
1811        let bin4 = bin.slice(0..3);
1812        assert_eq!(bin4, bytes![&env, [0, 1, 2]]);
1813
1814        let bin4 = bin.slice(3..5);
1815        assert_eq!(bin4, bytes![&env, [3, 4]]);
1816
1817        assert_eq!(bin, bytes![&env, [0, 1, 2, 3, 4]]); // makes sure original bytes is unchanged
1818    }
1819
1820    #[test]
1821    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1822    fn test_slice_panic() {
1823        let env = Env::default();
1824        let bin = bytes![&env, [0, 1, 2, 3, 4]];
1825        let _ = bin.slice(..=bin.len());
1826    }
1827
1828    #[test]
1829    fn test_bytes_to_string() {
1830        let env = Env::default();
1831        let b: Bytes = bytes![&env, [0, 1, 2, 3, 4]];
1832        let s: String = b.clone().into();
1833        assert_eq!(s.len(), 5);
1834        let mut slice = [0u8; 5];
1835        s.copy_into_slice(&mut slice);
1836        assert_eq!(slice, [0, 1, 2, 3, 4]);
1837        let s2 = b.to_string();
1838        assert_eq!(s, s2);
1839    }
1840}