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 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
365impl From<&Bytes> for String {
366 fn from(v: &Bytes) -> Self {
367 Env::bytes_to_string(&v.env, v.obj.clone())
368 .unwrap_infallible()
369 .into_val(&v.env)
370 }
371}
372
373impl From<Bytes> for String {
374 fn from(v: Bytes) -> Self {
375 (&v).into()
376 }
377}
378
379#[cfg(not(target_family = "wasm"))]
380impl From<&Bytes> for ScVal {
381 fn from(v: &Bytes) -> Self {
382 ScVal::try_from_val(&v.env, &v.obj.to_val()).unwrap()
388 }
389}
390
391#[cfg(not(target_family = "wasm"))]
392impl From<Bytes> for ScVal {
393 fn from(v: Bytes) -> Self {
394 (&v).into()
395 }
396}
397
398#[cfg(not(target_family = "wasm"))]
399impl TryFromVal<Env, ScVal> for Bytes {
400 type Error = ConversionError;
401 fn try_from_val(env: &Env, val: &ScVal) -> Result<Self, Self::Error> {
402 Ok(
403 BytesObject::try_from_val(env, &Val::try_from_val(env, val)?)?
404 .try_into_val(env)
405 .unwrap_infallible(),
406 )
407 }
408}
409
410impl TryFromVal<Env, &str> for Bytes {
411 type Error = ConversionError;
412
413 fn try_from_val(env: &Env, v: &&str) -> Result<Self, Self::Error> {
414 Ok(Bytes::from_slice(env, v.as_bytes()))
415 }
416}
417
418impl TryFromVal<Env, &[u8]> for Bytes {
419 type Error = ConversionError;
420
421 fn try_from_val(env: &Env, v: &&[u8]) -> Result<Self, Self::Error> {
422 Ok(Bytes::from_slice(env, v))
423 }
424}
425
426impl<const N: usize> TryFromVal<Env, [u8; N]> for Bytes {
427 type Error = ConversionError;
428
429 fn try_from_val(env: &Env, v: &[u8; N]) -> Result<Self, Self::Error> {
430 Ok(Bytes::from_array(env, v))
431 }
432}
433
434impl Bytes {
435 #[inline(always)]
436 pub(crate) unsafe fn unchecked_new(env: Env, obj: BytesObject) -> Self {
437 Self { env, obj }
438 }
439
440 #[inline(always)]
441 pub fn env(&self) -> &Env {
442 &self.env
443 }
444
445 pub fn as_val(&self) -> &Val {
446 self.obj.as_val()
447 }
448
449 pub fn to_val(&self) -> Val {
450 self.obj.to_val()
451 }
452
453 pub fn as_object(&self) -> &BytesObject {
454 &self.obj
455 }
456
457 pub fn to_object(&self) -> BytesObject {
458 self.obj
459 }
460}
461
462impl Bytes {
463 #[inline(always)]
465 pub fn new(env: &Env) -> Bytes {
466 let obj = env.bytes_new().unwrap_infallible();
467 unsafe { Self::unchecked_new(env.clone(), obj) }
468 }
469
470 #[inline(always)]
472 pub fn from_array<const N: usize>(env: &Env, items: &[u8; N]) -> Bytes {
473 Self::from_slice(env, items)
474 }
475
476 #[inline(always)]
478 pub fn from_slice(env: &Env, items: &[u8]) -> Bytes {
479 Bytes {
480 env: env.clone(),
481 obj: env.bytes_new_from_slice(items).unwrap_optimized(),
482 }
483 }
484
485 #[inline(always)]
491 pub fn set(&mut self, i: u32, v: u8) {
492 let v32: u32 = v.into();
493 self.obj = self
494 .env()
495 .bytes_put(self.obj, i.into(), v32.into())
496 .unwrap_infallible()
497 }
498
499 #[inline(always)]
501 pub fn get(&self, i: u32) -> Option<u8> {
502 if i < self.len() {
503 Some(self.get_unchecked(i))
504 } else {
505 None
506 }
507 }
508
509 #[inline(always)]
515 pub fn get_unchecked(&self, i: u32) -> u8 {
516 let res32_val = self.env().bytes_get(self.obj, i.into()).unwrap_infallible();
517 let res32: u32 = res32_val.into();
518 res32 as u8
519 }
520
521 #[inline(always)]
523 pub fn is_empty(&self) -> bool {
524 self.len() == 0
525 }
526
527 #[inline(always)]
529 pub fn len(&self) -> u32 {
530 self.env().bytes_len(self.obj).unwrap_infallible().into()
531 }
532
533 #[inline(always)]
535 pub fn first(&self) -> Option<u8> {
536 if !self.is_empty() {
537 Some(self.first_unchecked())
538 } else {
539 None
540 }
541 }
542
543 #[inline(always)]
549 pub fn first_unchecked(&self) -> u8 {
550 let res: u32 = self.env().bytes_front(self.obj).unwrap_infallible().into();
551 res as u8
552 }
553
554 #[inline(always)]
556 pub fn last(&self) -> Option<u8> {
557 if !self.is_empty() {
558 Some(self.last_unchecked())
559 } else {
560 None
561 }
562 }
563
564 #[inline(always)]
570 pub fn last_unchecked(&self) -> u8 {
571 let res: u32 = self.env().bytes_back(self.obj).unwrap_infallible().into();
572 res as u8
573 }
574
575 #[inline(always)]
579 pub fn remove(&mut self, i: u32) -> Option<()> {
580 if i < self.len() {
581 self.remove_unchecked(i);
582 Some(())
583 } else {
584 None
585 }
586 }
587
588 #[inline(always)]
594 pub fn remove_unchecked(&mut self, i: u32) {
595 self.obj = self.env().bytes_del(self.obj, i.into()).unwrap_infallible()
596 }
597
598 #[inline(always)]
602 pub fn push_back(&mut self, x: u8) {
603 let x32: u32 = x.into();
604 self.obj = self
605 .env()
606 .bytes_push(self.obj, x32.into())
607 .unwrap_infallible()
608 }
609
610 #[inline(always)]
612 pub fn pop_back(&mut self) -> Option<u8> {
613 let last = self.last()?;
614 self.obj = self.env().bytes_pop(self.obj).unwrap_infallible();
615 Some(last)
616 }
617
618 #[inline(always)]
624 pub fn pop_back_unchecked(&mut self) -> u8 {
625 let last = self.last_unchecked();
626 self.obj = self.env().bytes_pop(self.obj).unwrap_infallible();
627 last
628 }
629
630 #[inline(always)]
636 pub fn insert(&mut self, i: u32, b: u8) {
637 let b32: u32 = b.into();
638 self.obj = self
639 .env()
640 .bytes_insert(self.obj, i.into(), b32.into())
641 .unwrap_infallible()
642 }
643
644 #[inline(always)]
650 pub fn insert_from_bytes(&mut self, i: u32, bytes: Bytes) {
651 let mut result = self.slice(..i);
652 result.append(&bytes);
653 result.append(&self.slice(i..));
654 *self = result
655 }
656
657 #[inline(always)]
663 pub fn insert_from_array<const N: usize>(&mut self, i: u32, array: &[u8; N]) {
664 self.insert_from_slice(i, array)
665 }
666
667 #[inline(always)]
673 pub fn insert_from_slice(&mut self, i: u32, slice: &[u8]) {
674 self.insert_from_bytes(i, Bytes::from_slice(self.env(), slice))
675 }
676
677 #[inline(always)]
679 pub fn append(&mut self, other: &Bytes) {
680 self.obj = self
681 .env()
682 .bytes_append(self.obj, other.obj)
683 .unwrap_infallible()
684 }
685
686 #[inline(always)]
688 pub fn extend_from_array<const N: usize>(&mut self, array: &[u8; N]) {
689 self.extend_from_slice(array)
690 }
691
692 #[inline(always)]
694 pub fn extend_from_slice(&mut self, slice: &[u8]) {
695 self.obj = self
696 .env()
697 .bytes_copy_from_slice(self.to_object(), self.len().into(), slice)
698 .unwrap_optimized()
699 }
700
701 #[inline(always)]
706 pub fn copy_from_slice(&mut self, i: u32, slice: &[u8]) {
707 self.obj = self
708 .env()
709 .bytes_copy_from_slice(self.to_object(), i.into(), slice)
710 .unwrap_optimized()
711 }
712
713 #[inline(always)]
719 pub fn copy_into_slice(&self, slice: &mut [u8]) {
720 let env = self.env();
721 if self.len() as usize != slice.len() {
722 sdk_panic!("Bytes::copy_into_slice with mismatched slice length")
723 }
724 env.bytes_copy_to_slice(self.to_object(), Val::U32_ZERO, slice)
725 .unwrap_optimized();
726 }
727
728 #[must_use]
735 pub fn slice(&self, r: impl RangeBounds<u32>) -> Self {
736 let start_bound = match r.start_bound() {
737 Bound::Included(s) => *s,
738 Bound::Excluded(s) => *s + 1,
739 Bound::Unbounded => 0,
740 };
741 let end_bound = match r.end_bound() {
742 Bound::Included(s) => *s + 1,
743 Bound::Excluded(s) => *s,
744 Bound::Unbounded => self.len(),
745 };
746 let env = self.env();
747 let bin = env
748 .bytes_slice(self.obj, start_bound.into(), end_bound.into())
749 .unwrap_infallible();
750 unsafe { Self::unchecked_new(env.clone(), bin) }
751 }
752
753 pub fn iter(&self) -> BytesIter {
754 self.clone().into_iter()
755 }
756
757 #[must_use]
771 pub fn to_buffer<const B: usize>(&self) -> BytesBuffer<B> {
772 let mut buffer = [0u8; B];
773 let len = self.len() as usize;
774 {
775 let slice = &mut buffer[0..len];
776 self.copy_into_slice(slice);
777 }
778 BytesBuffer { buffer, len }
779 }
780
781 #[cfg(feature = "alloc")]
788 #[must_use]
789 pub fn to_alloc_vec(&self) -> alloc::vec::Vec<u8> {
790 let len = self.len() as usize;
791 let mut vec = alloc::vec::from_elem(0u8, len);
792 self.copy_into_slice(&mut vec);
793 vec
794 }
795
796 pub fn to_string(&self) -> String {
801 self.into()
802 }
803}
804
805#[derive(Debug, Clone, PartialEq, Eq)]
811pub struct BytesBuffer<const B: usize> {
812 buffer: [u8; B],
813 len: usize,
814}
815
816impl<const B: usize> Borrow<[u8]> for BytesBuffer<B> {
817 fn borrow(&self) -> &[u8] {
819 self.as_slice()
820 }
821}
822
823impl<const B: usize> BytesBuffer<B> {
824 pub fn as_slice(&self) -> &[u8] {
826 &self.buffer[..self.len]
827 }
828}
829
830impl IntoIterator for Bytes {
831 type Item = u8;
832 type IntoIter = BytesIter;
833
834 fn into_iter(self) -> Self::IntoIter {
835 BytesIter(self)
836 }
837}
838
839#[derive(Clone)]
840pub struct BytesIter(Bytes);
841
842impl BytesIter {
843 fn into_bin(self) -> Bytes {
844 self.0
845 }
846}
847
848impl Iterator for BytesIter {
849 type Item = u8;
850
851 fn next(&mut self) -> Option<Self::Item> {
852 if self.0.is_empty() {
853 None
854 } else {
855 let val: u32 = self
856 .0
857 .env()
858 .bytes_front(self.0.obj)
859 .unwrap_infallible()
860 .into();
861 self.0 = self.0.slice(1..);
862 Some(val as u8)
863 }
864 }
865
866 fn size_hint(&self) -> (usize, Option<usize>) {
867 let len = self.0.len() as usize;
868 (len, Some(len))
869 }
870}
871
872impl DoubleEndedIterator for BytesIter {
873 fn next_back(&mut self) -> Option<Self::Item> {
874 let len = self.0.len();
875 if len == 0 {
876 None
877 } else {
878 let val: u32 = self
879 .0
880 .env()
881 .bytes_back(self.0.obj)
882 .unwrap_infallible()
883 .into();
884 self.0 = self.0.slice(..len - 1);
885 Some(val as u8)
886 }
887 }
888}
889
890impl FusedIterator for BytesIter {}
891
892impl ExactSizeIterator for BytesIter {
893 fn len(&self) -> usize {
894 self.0.len() as usize
895 }
896}
897
898#[derive(Clone)]
927#[repr(transparent)]
928pub struct BytesN<const N: usize>(Bytes);
929
930impl<const N: usize> Debug for BytesN<N> {
931 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
932 write!(f, "BytesN<{}>(", N)?;
933 let mut iter = self.iter();
934 if let Some(x) = iter.next() {
935 write!(f, "{:?}", x)?;
936 }
937 for x in iter {
938 write!(f, ", {:?}", x)?;
939 }
940 write!(f, ")")?;
941 Ok(())
942 }
943}
944
945impl<const N: usize> Eq for BytesN<N> {}
946
947impl<const N: usize> PartialEq for BytesN<N> {
948 fn eq(&self, other: &Self) -> bool {
949 self.partial_cmp(other) == Some(Ordering::Equal)
950 }
951}
952
953impl<const N: usize> PartialEq<[u8; N]> for BytesN<N> {
954 fn eq(&self, other: &[u8; N]) -> bool {
955 let other: BytesN<N> = other.into_val(self.env());
956 self.eq(&other)
957 }
958}
959
960impl<const N: usize> PartialEq<BytesN<N>> for [u8; N] {
961 fn eq(&self, other: &BytesN<N>) -> bool {
962 let self_: BytesN<N> = self.into_val(other.env());
963 self_.eq(other)
964 }
965}
966
967impl<const N: usize> PartialOrd for BytesN<N> {
968 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
969 Some(Ord::cmp(self, other))
970 }
971}
972
973impl<const N: usize> PartialOrd<[u8; N]> for BytesN<N> {
974 fn partial_cmp(&self, other: &[u8; N]) -> Option<Ordering> {
975 let other: BytesN<N> = other.into_val(self.env());
976 self.partial_cmp(&other)
977 }
978}
979
980impl<const N: usize> PartialOrd<BytesN<N>> for [u8; N] {
981 fn partial_cmp(&self, other: &BytesN<N>) -> Option<Ordering> {
982 let self_: BytesN<N> = self.into_val(other.env());
983 self_.partial_cmp(other)
984 }
985}
986
987impl<const N: usize> Ord for BytesN<N> {
988 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
989 self.0.cmp(&other.0)
990 }
991}
992
993impl<const N: usize> Borrow<Bytes> for BytesN<N> {
994 fn borrow(&self) -> &Bytes {
995 &self.0
996 }
997}
998
999impl<const N: usize> Borrow<Bytes> for &BytesN<N> {
1000 fn borrow(&self) -> &Bytes {
1001 &self.0
1002 }
1003}
1004
1005impl<const N: usize> Borrow<Bytes> for &mut BytesN<N> {
1006 fn borrow(&self) -> &Bytes {
1007 &self.0
1008 }
1009}
1010
1011impl<const N: usize> AsRef<Bytes> for BytesN<N> {
1012 fn as_ref(&self) -> &Bytes {
1013 &self.0
1014 }
1015}
1016
1017impl<const N: usize> TryFromVal<Env, BytesN<N>> for BytesN<N> {
1018 type Error = ConversionError;
1019
1020 fn try_from_val(_env: &Env, v: &BytesN<N>) -> Result<Self, Self::Error> {
1021 Ok(v.clone())
1022 }
1023}
1024
1025impl<const N: usize> TryFromVal<Env, BytesN<N>> for Bytes {
1026 type Error = ConversionError;
1027
1028 fn try_from_val(_env: &Env, v: &BytesN<N>) -> Result<Self, Self::Error> {
1029 Ok(v.0.clone())
1030 }
1031}
1032
1033impl<const N: usize> TryFromVal<Env, [u8; N]> for BytesN<N> {
1034 type Error = ConversionError;
1035
1036 fn try_from_val(env: &Env, v: &[u8; N]) -> Result<Self, Self::Error> {
1037 Ok(BytesN::from_array(env, v))
1038 }
1039}
1040
1041impl<const N: usize> TryFromVal<Env, BytesN<N>> for [u8; N] {
1042 type Error = ConversionError;
1043
1044 fn try_from_val(_env: &Env, v: &BytesN<N>) -> Result<Self, Self::Error> {
1045 Ok(v.to_array())
1046 }
1047}
1048
1049impl<const N: usize> TryFromVal<Env, BytesObject> for BytesN<N> {
1050 type Error = ConversionError;
1051
1052 fn try_from_val(env: &Env, obj: &BytesObject) -> Result<Self, Self::Error> {
1053 Bytes::try_from_val(env, obj).unwrap_infallible().try_into()
1054 }
1055}
1056
1057impl<const N: usize> TryFromVal<Env, Val> for BytesN<N> {
1058 type Error = ConversionError;
1059
1060 fn try_from_val(env: &Env, val: &Val) -> Result<Self, Self::Error> {
1061 Bytes::try_from_val(env, val)?.try_into()
1062 }
1063}
1064
1065impl<const N: usize> TryFromVal<Env, BytesN<N>> for Val {
1066 type Error = ConversionError;
1067
1068 fn try_from_val(_env: &Env, v: &BytesN<N>) -> Result<Self, Self::Error> {
1069 Ok(v.to_val())
1070 }
1071}
1072
1073impl<const N: usize> TryFromVal<Env, &BytesN<N>> for Val {
1074 type Error = ConversionError;
1075
1076 fn try_from_val(_env: &Env, v: &&BytesN<N>) -> Result<Self, Self::Error> {
1077 Ok(v.to_val())
1078 }
1079}
1080
1081impl<const N: usize> TryFrom<Bytes> for BytesN<N> {
1082 type Error = ConversionError;
1083
1084 #[inline(always)]
1085 fn try_from(bin: Bytes) -> Result<Self, Self::Error> {
1086 if bin.len() == { N as u32 } {
1087 Ok(Self(bin))
1088 } else {
1089 Err(ConversionError {})
1090 }
1091 }
1092}
1093
1094impl<const N: usize> TryFrom<&Bytes> for BytesN<N> {
1095 type Error = ConversionError;
1096
1097 #[inline(always)]
1098 fn try_from(bin: &Bytes) -> Result<Self, Self::Error> {
1099 bin.clone().try_into()
1100 }
1101}
1102
1103impl<const N: usize> From<BytesN<N>> for Val {
1104 #[inline(always)]
1105 fn from(v: BytesN<N>) -> Self {
1106 v.0.into()
1107 }
1108}
1109
1110impl<const N: usize> From<BytesN<N>> for Bytes {
1111 #[inline(always)]
1112 fn from(v: BytesN<N>) -> Self {
1113 v.0
1114 }
1115}
1116
1117impl<const N: usize> From<&BytesN<N>> for Bytes {
1118 #[inline(always)]
1119 fn from(v: &BytesN<N>) -> Self {
1120 v.0.clone()
1121 }
1122}
1123
1124#[cfg(not(target_family = "wasm"))]
1125impl<const N: usize> From<&BytesN<N>> for ScVal {
1126 fn from(v: &BytesN<N>) -> Self {
1127 ScVal::try_from_val(&v.0.env, &v.0.obj.to_val()).unwrap()
1133 }
1134}
1135
1136#[cfg(not(target_family = "wasm"))]
1137impl<const N: usize> From<BytesN<N>> for ScVal {
1138 fn from(v: BytesN<N>) -> Self {
1139 (&v).into()
1140 }
1141}
1142
1143#[cfg(not(target_family = "wasm"))]
1144impl<const N: usize> TryFromVal<Env, ScVal> for BytesN<N> {
1145 type Error = ConversionError;
1146 fn try_from_val(env: &Env, val: &ScVal) -> Result<Self, Self::Error> {
1147 Bytes::try_from_val(env, val)?.try_into()
1148 }
1149}
1150
1151impl<const N: usize> BytesN<N> {
1152 #[inline(always)]
1153 pub(crate) unsafe fn unchecked_new(env: Env, obj: BytesObject) -> Self {
1154 Self(Bytes::unchecked_new(env, obj))
1155 }
1156
1157 pub fn env(&self) -> &Env {
1158 self.0.env()
1159 }
1160
1161 pub fn as_val(&self) -> &Val {
1162 self.0.as_val()
1163 }
1164
1165 pub fn to_val(&self) -> Val {
1166 self.0.to_val()
1167 }
1168
1169 pub fn as_object(&self) -> &BytesObject {
1170 self.0.as_object()
1171 }
1172
1173 pub fn to_object(&self) -> BytesObject {
1174 self.0.to_object()
1175 }
1176
1177 #[inline(always)]
1179 pub fn from_array(env: &Env, items: &[u8; N]) -> BytesN<N> {
1180 BytesN(Bytes::from_slice(env, items))
1181 }
1182
1183 #[inline(always)]
1189 pub fn set(&mut self, i: u32, v: u8) {
1190 self.0.set(i, v);
1191 }
1192
1193 #[inline(always)]
1195 pub fn get(&self, i: u32) -> Option<u8> {
1196 self.0.get(i)
1197 }
1198
1199 #[inline(always)]
1205 pub fn get_unchecked(&self, i: u32) -> u8 {
1206 self.0.get_unchecked(i)
1207 }
1208
1209 #[inline(always)]
1211 pub fn is_empty(&self) -> bool {
1212 false
1213 }
1214
1215 #[inline(always)]
1217 pub fn len(&self) -> u32 {
1218 N as u32
1219 }
1220
1221 #[inline(always)]
1223 pub fn first(&self) -> Option<u8> {
1224 self.0.first()
1225 }
1226
1227 #[inline(always)]
1233 pub fn first_unchecked(&self) -> u8 {
1234 self.0.first_unchecked()
1235 }
1236
1237 #[inline(always)]
1239 pub fn last(&self) -> Option<u8> {
1240 self.0.last()
1241 }
1242
1243 #[inline(always)]
1249 pub fn last_unchecked(&self) -> u8 {
1250 self.0.last_unchecked()
1251 }
1252
1253 #[inline(always)]
1255 pub fn copy_into_slice(&self, slice: &mut [u8; N]) {
1256 let env = self.env();
1257 env.bytes_copy_to_slice(self.to_object(), Val::U32_ZERO, slice)
1258 .unwrap_optimized();
1259 }
1260
1261 #[inline(always)]
1263 pub fn to_array(&self) -> [u8; N] {
1264 let mut array = [0u8; N];
1265 self.copy_into_slice(&mut array);
1266 array
1267 }
1268
1269 pub fn iter(&self) -> BytesIter {
1270 self.clone().into_iter()
1271 }
1272}
1273
1274#[cfg(any(test, feature = "testutils"))]
1275#[cfg_attr(feature = "docs", doc(cfg(feature = "testutils")))]
1276impl<const N: usize> crate::testutils::BytesN<N> for BytesN<N> {
1277 fn random(env: &Env) -> BytesN<N> {
1278 BytesN::from_array(env, &crate::testutils::random())
1279 }
1280}
1281
1282impl<const N: usize> IntoIterator for BytesN<N> {
1283 type Item = u8;
1284
1285 type IntoIter = BytesIter;
1286
1287 fn into_iter(self) -> Self::IntoIter {
1288 BytesIter(self.0)
1289 }
1290}
1291
1292impl<const N: usize> TryFrom<Bytes> for [u8; N] {
1293 type Error = ConversionError;
1294
1295 fn try_from(bin: Bytes) -> Result<Self, Self::Error> {
1296 let fixed: BytesN<N> = bin.try_into()?;
1297 Ok(fixed.into())
1298 }
1299}
1300
1301impl<const N: usize> TryFrom<&Bytes> for [u8; N] {
1302 type Error = ConversionError;
1303
1304 fn try_from(bin: &Bytes) -> Result<Self, Self::Error> {
1305 let fixed: BytesN<N> = bin.try_into()?;
1306 Ok(fixed.into())
1307 }
1308}
1309
1310impl<const N: usize> From<BytesN<N>> for [u8; N] {
1311 fn from(bin: BytesN<N>) -> Self {
1312 let mut res = [0u8; N];
1313 for (i, b) in bin.into_iter().enumerate() {
1314 res[i] = b;
1315 }
1316 res
1317 }
1318}
1319
1320impl<const N: usize> From<&BytesN<N>> for [u8; N] {
1321 fn from(bin: &BytesN<N>) -> Self {
1322 let mut res = [0u8; N];
1323 for (i, b) in bin.iter().enumerate() {
1324 res[i] = b;
1325 }
1326 res
1327 }
1328}
1329
1330#[cfg(test)]
1331mod test {
1332 use super::*;
1333
1334 #[test]
1335 fn bytes_from_and_to_slices() {
1336 let env = Env::default();
1337
1338 let b = Bytes::from_slice(&env, &[1, 2, 3, 4]);
1339 let mut out = [0u8; 4];
1340 b.copy_into_slice(&mut out);
1341 assert_eq!([1, 2, 3, 4], out);
1342
1343 let mut b = Bytes::from_slice(&env, &[1, 2, 3, 4]);
1344 b.extend_from_slice(&[5, 6, 7, 8]);
1345 b.insert_from_slice(1, &[9, 10]);
1346 b.insert_from_bytes(4, Bytes::from_slice(&env, &[0, 0]));
1347 let mut out = [0u8; 12];
1348 b.copy_into_slice(&mut out);
1349 assert_eq!([1, 9, 10, 2, 0, 0, 3, 4, 5, 6, 7, 8], out);
1350 b.copy_from_slice(3, &[7, 6, 5]);
1351 b.copy_into_slice(&mut out);
1352 assert_eq!([1, 9, 10, 7, 6, 5, 3, 4, 5, 6, 7, 8], out);
1353 }
1354
1355 #[test]
1356 fn bytesn_from_and_to_slices() {
1357 let env = Env::default();
1358
1359 let b = BytesN::from_array(&env, &[1, 2, 3, 4]);
1360 let mut out = [0u8; 4];
1361 b.copy_into_slice(&mut out);
1362 assert_eq!([1, 2, 3, 4], out);
1363 }
1364
1365 #[test]
1366 #[should_panic]
1367 fn bytes_to_short_slice() {
1368 let env = Env::default();
1369 let b = Bytes::from_slice(&env, &[1, 2, 3, 4]);
1370 let mut out = [0u8; 3];
1371 b.copy_into_slice(&mut out);
1372 }
1373
1374 #[test]
1375 #[should_panic]
1376 fn bytes_to_long_slice() {
1377 let env = Env::default();
1378 let b = Bytes::from_slice(&env, &[1, 2, 3, 4]);
1379 let mut out = [0u8; 5];
1380 b.copy_into_slice(&mut out);
1381 }
1382
1383 #[test]
1384 fn macro_bytes() {
1385 let env = Env::default();
1386 assert_eq!(bytes!(&env), Bytes::new(&env));
1387 assert_eq!(bytes!(&env, 1), {
1388 let mut b = Bytes::new(&env);
1389 b.push_back(1);
1390 b
1391 });
1392 assert_eq!(bytes!(&env, 1,), {
1393 let mut b = Bytes::new(&env);
1394 b.push_back(1);
1395 b
1396 });
1397 assert_eq!(bytes!(&env, [3, 2, 1,]), {
1398 let mut b = Bytes::new(&env);
1399 b.push_back(3);
1400 b.push_back(2);
1401 b.push_back(1);
1402 b
1403 });
1404 }
1405
1406 #[test]
1407 fn macro_bytes_hex() {
1408 let env = Env::default();
1409 assert_eq!(bytes!(&env), Bytes::new(&env));
1410 assert_eq!(bytes!(&env, 1), {
1411 let mut b = Bytes::new(&env);
1412 b.push_back(1);
1413 b
1414 });
1415 assert_eq!(bytes!(&env, 1,), {
1416 let mut b = Bytes::new(&env);
1417 b.push_back(1);
1418 b
1419 });
1420 assert_eq!(bytes!(&env, 0x30201), {
1421 let mut b = Bytes::new(&env);
1422 b.push_back(3);
1423 b.push_back(2);
1424 b.push_back(1);
1425 b
1426 });
1427 assert_eq!(bytes!(&env, 0x0000030201), {
1428 Bytes::from_array(&env, &[0, 0, 3, 2, 1])
1429 });
1430 }
1431
1432 #[test]
1433 fn macro_bytesn() {
1434 let env = Env::default();
1435 assert_eq!(bytesn!(&env, 1), { BytesN::from_array(&env, &[1]) });
1436 assert_eq!(bytesn!(&env, 1,), { BytesN::from_array(&env, &[1]) });
1437 assert_eq!(bytesn!(&env, [3, 2, 1,]), {
1438 BytesN::from_array(&env, &[3, 2, 1])
1439 });
1440 }
1441
1442 #[test]
1443 fn macro_bytesn_hex() {
1444 let env = Env::default();
1445 assert_eq!(bytesn!(&env, 0x030201), {
1446 BytesN::from_array(&env, &[3, 2, 1])
1447 });
1448 assert_eq!(bytesn!(&env, 0x0000030201), {
1449 BytesN::from_array(&env, &[0, 0, 3, 2, 1])
1450 });
1451 }
1452
1453 #[test]
1454 fn test_bin() {
1455 let env = Env::default();
1456
1457 let mut bin = Bytes::new(&env);
1458 assert_eq!(bin.len(), 0);
1459 bin.push_back(10);
1460 assert_eq!(bin.len(), 1);
1461 bin.push_back(20);
1462 assert_eq!(bin.len(), 2);
1463 bin.push_back(30);
1464 assert_eq!(bin.len(), 3);
1465 println!("{:?}", bin);
1466
1467 let bin_ref = &bin;
1468 assert_eq!(bin_ref.len(), 3);
1469
1470 let mut bin_copy = bin.clone();
1471 assert!(bin == bin_copy);
1472 assert_eq!(bin_copy.len(), 3);
1473 bin_copy.push_back(40);
1474 assert_eq!(bin_copy.len(), 4);
1475 assert!(bin != bin_copy);
1476
1477 assert_eq!(bin.len(), 3);
1478 assert_eq!(bin_ref.len(), 3);
1479
1480 bin_copy.pop_back();
1481 assert!(bin == bin_copy);
1482
1483 let bad_fixed: Result<BytesN<4>, ConversionError> = bin.try_into();
1484 assert!(bad_fixed.is_err());
1485 let fixed: BytesN<3> = bin_copy.try_into().unwrap();
1486 println!("{:?}", fixed);
1487 }
1488
1489 #[test]
1490 fn test_bin_iter() {
1491 let env = Env::default();
1492 let mut bin = Bytes::new(&env);
1493 bin.push_back(10);
1494 bin.push_back(20);
1495 bin.push_back(30);
1496 let mut iter = bin.iter();
1497 assert_eq!(iter.next(), Some(10));
1498 assert_eq!(iter.next(), Some(20));
1499 assert_eq!(iter.next(), Some(30));
1500 assert_eq!(iter.next(), None);
1501 assert_eq!(iter.next(), None);
1502 let mut iter = bin.iter();
1503 assert_eq!(iter.next(), Some(10));
1504 assert_eq!(iter.next_back(), Some(30));
1505 assert_eq!(iter.next_back(), Some(20));
1506 assert_eq!(iter.next_back(), None);
1507 assert_eq!(iter.next_back(), None);
1508
1509 let fixed: BytesN<3> = bin.try_into().unwrap();
1510 let mut iter = fixed.iter();
1511 assert_eq!(iter.next(), Some(10));
1512 assert_eq!(iter.next(), Some(20));
1513 assert_eq!(iter.next(), Some(30));
1514 assert_eq!(iter.next(), None);
1515 assert_eq!(iter.next(), None);
1516 let mut iter = fixed.iter();
1517 assert_eq!(iter.next(), Some(10));
1518 assert_eq!(iter.next_back(), Some(30));
1519 assert_eq!(iter.next_back(), Some(20));
1520 assert_eq!(iter.next_back(), None);
1521 assert_eq!(iter.next_back(), None);
1522 }
1523
1524 #[test]
1525 fn test_array_binary_borrow() {
1526 fn get_len(b: impl Borrow<Bytes>) -> u32 {
1527 let b: &Bytes = b.borrow();
1528 b.len()
1529 }
1530
1531 let env = Env::default();
1532 let mut bin = Bytes::new(&env);
1533 bin.push_back(10);
1534 bin.push_back(20);
1535 bin.push_back(30);
1536 assert_eq!(bin.len(), 3);
1537
1538 let arr_bin: BytesN<3> = bin.clone().try_into().unwrap();
1539 assert_eq!(arr_bin.len(), 3);
1540
1541 assert_eq!(get_len(&bin), 3);
1542 assert_eq!(get_len(bin), 3);
1543 assert_eq!(get_len(&arr_bin), 3);
1544 assert_eq!(get_len(arr_bin), 3);
1545 }
1546
1547 #[test]
1548 fn bytesn_debug() {
1549 let env = Env::default();
1550 let mut bin = Bytes::new(&env);
1551 bin.push_back(10);
1552 bin.push_back(20);
1553 bin.push_back(30);
1554 let arr_bin: BytesN<3> = bin.clone().try_into().unwrap();
1555 assert_eq!(format!("{:?}", arr_bin), "BytesN<3>(10, 20, 30)");
1556 }
1557
1558 #[test]
1559 fn test_is_empty() {
1560 let env = Env::default();
1561 let mut bin = Bytes::new(&env);
1562 assert_eq!(bin.is_empty(), true);
1563 bin.push_back(10);
1564 assert_eq!(bin.is_empty(), false);
1565 }
1566
1567 #[test]
1568 fn test_first() {
1569 let env = Env::default();
1570 let mut bin = bytes![&env, [1, 2, 3, 4]];
1571
1572 assert_eq!(bin.first(), Some(1));
1573 bin.remove(0);
1574 assert_eq!(bin.first(), Some(2));
1575
1576 let bin = bytes![&env];
1578 assert_eq!(bin.first(), None);
1579 }
1580
1581 #[test]
1582 fn test_first_unchecked() {
1583 let env = Env::default();
1584 let mut bin = bytes![&env, [1, 2, 3, 4]];
1585
1586 assert_eq!(bin.first_unchecked(), 1);
1587 bin.remove(0);
1588 assert_eq!(bin.first_unchecked(), 2);
1589 }
1590
1591 #[test]
1592 #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1593 fn test_first_unchecked_panics() {
1594 let env = Env::default();
1595 let bin = bytes![&env];
1596 bin.first_unchecked();
1597 }
1598
1599 #[test]
1600 fn test_last() {
1601 let env = Env::default();
1602 let mut bin = bytes![&env, [1, 2, 3, 4]];
1603
1604 assert_eq!(bin.last(), Some(4));
1605 bin.remove(3);
1606 assert_eq!(bin.last(), Some(3));
1607
1608 let bin = bytes![&env];
1610 assert_eq!(bin.last(), None);
1611 }
1612
1613 #[test]
1614 fn test_last_unchecked() {
1615 let env = Env::default();
1616 let mut bin = bytes![&env, [1, 2, 3, 4]];
1617
1618 assert_eq!(bin.last_unchecked(), 4);
1619 bin.remove(3);
1620 assert_eq!(bin.last_unchecked(), 3);
1621 }
1622
1623 #[test]
1624 #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1625 fn test_last_unchecked_panics() {
1626 let env = Env::default();
1627 let bin = bytes![&env];
1628 bin.last_unchecked();
1629 }
1630
1631 #[test]
1632 fn test_get() {
1633 let env = Env::default();
1634 let bin = bytes![&env, [0, 1, 5, 2, 8]];
1635
1636 assert_eq!(bin.get(0), Some(0));
1637 assert_eq!(bin.get(1), Some(1));
1638 assert_eq!(bin.get(2), Some(5));
1639 assert_eq!(bin.get(3), Some(2));
1640 assert_eq!(bin.get(4), Some(8));
1641
1642 assert_eq!(bin.get(bin.len()), None);
1643 assert_eq!(bin.get(bin.len() + 1), None);
1644 assert_eq!(bin.get(u32::MAX), None);
1645
1646 let bin = bytes![&env];
1648 assert_eq!(bin.get(0), None);
1649 assert_eq!(bin.get(bin.len()), None);
1650 assert_eq!(bin.get(bin.len() + 1), None);
1651 assert_eq!(bin.get(u32::MAX), None);
1652 }
1653
1654 #[test]
1655 fn test_get_unchecked() {
1656 let env = Env::default();
1657 let bin = bytes![&env, [0, 1, 5, 2, 8]];
1658
1659 assert_eq!(bin.get_unchecked(0), 0);
1660 assert_eq!(bin.get_unchecked(1), 1);
1661 assert_eq!(bin.get_unchecked(2), 5);
1662 assert_eq!(bin.get_unchecked(3), 2);
1663 assert_eq!(bin.get_unchecked(4), 8);
1664 }
1665
1666 #[test]
1667 #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1668 fn test_get_unchecked_panics() {
1669 let env = Env::default();
1670 let bin = bytes![&env];
1671 bin.get_unchecked(0);
1672 }
1673
1674 #[test]
1675 fn test_remove() {
1676 let env = Env::default();
1677 let mut bin = bytes![&env, [1, 2, 3, 4]];
1678
1679 assert_eq!(bin.remove(2), Some(()));
1680 assert_eq!(bin, bytes![&env, [1, 2, 4]]);
1681 assert_eq!(bin.len(), 3);
1682
1683 assert_eq!(bin.remove(bin.len()), None);
1685 assert_eq!(bin.remove(bin.len() + 1), None);
1686 assert_eq!(bin.remove(u32::MAX), None);
1687
1688 assert_eq!(bin.remove(0), Some(()));
1690 assert_eq!(bin.remove(0), Some(()));
1691 assert_eq!(bin.remove(0), Some(()));
1692 assert_eq!(bin, bytes![&env]);
1693 assert_eq!(bin.len(), 0);
1694
1695 let mut bin = bytes![&env];
1697 assert_eq!(bin.remove(0), None);
1698 assert_eq!(bin.remove(bin.len()), None);
1699 assert_eq!(bin.remove(bin.len() + 1), None);
1700 assert_eq!(bin.remove(u32::MAX), None);
1701 }
1702
1703 #[test]
1704 fn test_remove_unchecked() {
1705 let env = Env::default();
1706 let mut bin = bytes![&env, [1, 2, 3, 4]];
1707
1708 bin.remove_unchecked(2);
1709 assert_eq!(bin, bytes![&env, [1, 2, 4]]);
1710 assert_eq!(bin.len(), 3);
1711 }
1712
1713 #[test]
1714 #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1715 fn test_remove_unchecked_panics() {
1716 let env = Env::default();
1717 let mut bin = bytes![&env, [1, 2, 3, 4]];
1718 bin.remove_unchecked(bin.len());
1719 }
1720
1721 #[test]
1722 fn test_pop() {
1723 let env = Env::default();
1724 let mut bin = bytes![&env, [0, 1, 2, 3, 4]];
1725
1726 assert_eq!(bin.pop_back(), Some(4));
1727 assert_eq!(bin.pop_back(), Some(3));
1728 assert_eq!(bin.len(), 3);
1729 assert_eq!(bin, bytes![&env, [0, 1, 2]]);
1730
1731 let mut bin = bytes![&env];
1733 assert_eq!(bin.pop_back(), None);
1734 }
1735
1736 #[test]
1737 fn test_pop_unchecked() {
1738 let env = Env::default();
1739 let mut bin = bytes![&env, [0, 1, 2, 3, 4]];
1740
1741 assert_eq!(bin.pop_back_unchecked(), 4);
1742 assert_eq!(bin.pop_back_unchecked(), 3);
1743 assert_eq!(bin.len(), 3);
1744 assert_eq!(bin, bytes![&env, [0, 1, 2]]);
1745 }
1746
1747 #[test]
1748 #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1749 fn test_pop_unchecked_panics() {
1750 let env = Env::default();
1751 let mut bin = bytes![&env];
1752 bin.pop_back_unchecked();
1753 }
1754
1755 #[test]
1756 fn test_insert() {
1757 let env = Env::default();
1758 let mut bin = bytes![&env, [0, 1, 2, 3, 4]];
1759
1760 bin.insert(3, 42);
1761 assert_eq!(bin, bytes![&env, [0, 1, 2, 42, 3, 4]]);
1762
1763 bin.insert(0, 43);
1765 assert_eq!(bin, bytes![&env, [43, 0, 1, 2, 42, 3, 4]]);
1766
1767 bin.insert(bin.len(), 44);
1769 assert_eq!(bin, bytes![&env, [43, 0, 1, 2, 42, 3, 4, 44]]);
1770 }
1771
1772 #[test]
1773 #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1774 fn test_insert_panic() {
1775 let env = Env::default();
1776 let mut bin = bytes![&env, [0, 1, 2, 3, 4]];
1777 bin.insert(80, 44);
1778 }
1779
1780 #[test]
1781 fn test_slice() {
1782 let env = Env::default();
1783 let bin = bytes![&env, [0, 1, 2, 3, 4]];
1784
1785 let bin2 = bin.slice(2..);
1786 assert_eq!(bin2, bytes![&env, [2, 3, 4]]);
1787
1788 let bin3 = bin.slice(3..3);
1789 assert_eq!(bin3, bytes![&env]);
1790
1791 let bin4 = bin.slice(0..3);
1792 assert_eq!(bin4, bytes![&env, [0, 1, 2]]);
1793
1794 let bin4 = bin.slice(3..5);
1795 assert_eq!(bin4, bytes![&env, [3, 4]]);
1796
1797 assert_eq!(bin, bytes![&env, [0, 1, 2, 3, 4]]); }
1799
1800 #[test]
1801 #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1802 fn test_slice_panic() {
1803 let env = Env::default();
1804 let bin = bytes![&env, [0, 1, 2, 3, 4]];
1805 let _ = bin.slice(..=bin.len());
1806 }
1807
1808 #[test]
1809 fn test_bytes_to_string() {
1810 let env = Env::default();
1811 let b: Bytes = bytes![&env, [0, 1, 2, 3, 4]];
1812 let s: String = b.clone().into();
1813 assert_eq!(s.len(), 5);
1814 let mut slice = [0u8; 5];
1815 s.copy_into_slice(&mut slice);
1816 assert_eq!(slice, [0, 1, 2, 3, 4]);
1817 let s2 = b.to_string();
1818 assert_eq!(s, s2);
1819 }
1820}