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