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