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