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