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