1#[cfg(feature = "alloc")]
2extern crate alloc;
3
4use core::{
5 borrow::Borrow,
6 cmp::Ordering,
7 convert::Infallible,
8 fmt::Debug,
9 iter::FusedIterator,
10 ops::{Bound, RangeBounds},
11};
12
13use super::{
14 env::internal::{BytesObject, Env as _, EnvBase as _},
15 env::IntoVal,
16 ConversionError, Env, TryFromVal, TryIntoVal, Val,
17};
18
19use crate::unwrap::{UnwrapInfallible, UnwrapOptimized};
20#[cfg(doc)]
21use crate::{storage::Storage, Map, Vec};
22
23#[cfg(not(target_family = "wasm"))]
24use super::xdr::ScVal;
25
26#[macro_export]
59macro_rules! bytes {
60 ($env:expr $(,)?) => {
61 $crate::Bytes::new($env)
62 };
63 ($env:expr, [$($x:expr),+ $(,)?] $(,)?) => {
64 $crate::Bytes::from_array($env, &[$($x),+])
65 };
66 ($env:expr, $x:tt $(,)?) => {
67 $crate::Bytes::from_array($env, &$crate::reexports_for_macros::bytes_lit::bytes!($x))
68 };
69}
70
71#[macro_export]
96macro_rules! bytesn {
97 ($env:expr, [$($x:expr),+ $(,)?] $(,)?) => {
98 $crate::BytesN::from_array($env, &[$($x),+])
99 };
100 ($env:expr, $x:tt $(,)?) => {
101 $crate::BytesN::from_array($env, &$crate::reexports_for_macros::bytes_lit::bytes!($x))
102 };
103}
104
105#[macro_export]
106macro_rules! impl_bytesn_repr {
107 ($elem: ident, $size: literal) => {
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 IntoVal<Env, Val> for $elem {
147 fn into_val(&self, e: &Env) -> Val {
148 self.0.into_val(e)
149 }
150 }
151
152 impl TryFromVal<Env, Val> for $elem {
153 type Error = ConversionError;
154
155 fn try_from_val(env: &Env, val: &Val) -> Result<Self, Self::Error> {
156 let bytes = <BytesN<$size>>::try_from_val(env, val)?;
157 Ok($elem(bytes))
158 }
159 }
160
161 impl IntoVal<Env, BytesN<$size>> for $elem {
162 fn into_val(&self, _e: &Env) -> BytesN<$size> {
163 self.0.clone()
164 }
165 }
166
167 impl From<$elem> for Bytes {
168 fn from(v: $elem) -> Self {
169 v.0.into()
170 }
171 }
172
173 impl From<$elem> for BytesN<$size> {
174 fn from(v: $elem) -> Self {
175 v.0
176 }
177 }
178
179 impl Into<[u8; $size]> for $elem {
180 fn into(self) -> [u8; $size] {
181 self.0.into()
182 }
183 }
184
185 impl Eq for $elem {}
186
187 impl PartialEq for $elem {
188 fn eq(&self, other: &Self) -> bool {
189 self.0.partial_cmp(other.as_bytes()) == Some(Ordering::Equal)
190 }
191 }
192
193 impl Debug for $elem {
194 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
195 write!(f, "{}({:?})", stringify!($elem), self.to_array())
196 }
197 }
198 };
199}
200
201#[derive(Clone)]
223pub struct Bytes {
224 env: Env,
225 obj: BytesObject,
226}
227
228impl Debug for Bytes {
229 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
230 write!(f, "Bytes(")?;
231 let mut iter = self.iter();
232 if let Some(x) = iter.next() {
233 write!(f, "{:?}", x)?;
234 }
235 for x in iter {
236 write!(f, ", {:?}", x)?;
237 }
238 write!(f, ")")?;
239 Ok(())
240 }
241}
242
243impl Eq for Bytes {}
244
245impl PartialEq for Bytes {
246 fn eq(&self, other: &Self) -> bool {
247 self.partial_cmp(other) == Some(Ordering::Equal)
248 }
249}
250
251impl PartialOrd for Bytes {
252 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
253 Some(Ord::cmp(self, other))
254 }
255}
256
257impl Ord for Bytes {
258 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
259 #[cfg(not(target_family = "wasm"))]
260 if !self.env.is_same_env(&other.env) {
261 return ScVal::from(self).cmp(&ScVal::from(other));
262 }
263 let v = self
264 .env
265 .obj_cmp(self.obj.to_val(), other.obj.to_val())
266 .unwrap_infallible();
267 v.cmp(&0)
268 }
269}
270
271impl TryFromVal<Env, Bytes> for Bytes {
272 type Error = ConversionError;
273
274 fn try_from_val(_env: &Env, v: &Bytes) -> Result<Self, Self::Error> {
275 Ok(v.clone())
276 }
277}
278
279impl TryFromVal<Env, BytesObject> for Bytes {
280 type Error = Infallible;
281
282 fn try_from_val(env: &Env, val: &BytesObject) -> Result<Self, Self::Error> {
283 Ok(unsafe { Bytes::unchecked_new(env.clone(), *val) })
284 }
285}
286
287impl TryFromVal<Env, Val> for Bytes {
288 type Error = ConversionError;
289
290 fn try_from_val(env: &Env, val: &Val) -> Result<Self, Self::Error> {
291 Ok(BytesObject::try_from_val(env, val)?
292 .try_into_val(env)
293 .unwrap_infallible())
294 }
295}
296
297impl TryFromVal<Env, Bytes> for Val {
298 type Error = ConversionError;
299
300 fn try_from_val(_env: &Env, v: &Bytes) -> Result<Self, Self::Error> {
301 Ok(v.to_val())
302 }
303}
304
305impl TryFromVal<Env, &Bytes> for Val {
306 type Error = ConversionError;
307
308 fn try_from_val(_env: &Env, v: &&Bytes) -> Result<Self, Self::Error> {
309 Ok(v.to_val())
310 }
311}
312
313impl From<Bytes> for Val {
314 #[inline(always)]
315 fn from(v: Bytes) -> Self {
316 v.obj.into()
317 }
318}
319
320impl From<Bytes> for BytesObject {
321 #[inline(always)]
322 fn from(v: Bytes) -> Self {
323 v.obj
324 }
325}
326
327impl From<&Bytes> for BytesObject {
328 #[inline(always)]
329 fn from(v: &Bytes) -> Self {
330 v.obj
331 }
332}
333
334impl From<&Bytes> for Bytes {
335 #[inline(always)]
336 fn from(v: &Bytes) -> Self {
337 v.clone()
338 }
339}
340
341#[cfg(not(target_family = "wasm"))]
342impl From<&Bytes> for ScVal {
343 fn from(v: &Bytes) -> Self {
344 ScVal::try_from_val(&v.env, &v.obj.to_val()).unwrap()
350 }
351}
352
353#[cfg(not(target_family = "wasm"))]
354impl From<Bytes> for ScVal {
355 fn from(v: Bytes) -> Self {
356 (&v).into()
357 }
358}
359
360#[cfg(not(target_family = "wasm"))]
361impl TryFromVal<Env, ScVal> for Bytes {
362 type Error = ConversionError;
363 fn try_from_val(env: &Env, val: &ScVal) -> Result<Self, Self::Error> {
364 Ok(
365 BytesObject::try_from_val(env, &Val::try_from_val(env, val)?)?
366 .try_into_val(env)
367 .unwrap_infallible(),
368 )
369 }
370}
371
372impl TryFromVal<Env, &str> for Bytes {
373 type Error = ConversionError;
374
375 fn try_from_val(env: &Env, v: &&str) -> Result<Self, Self::Error> {
376 Ok(Bytes::from_slice(env, v.as_bytes()))
377 }
378}
379
380impl TryFromVal<Env, &[u8]> for Bytes {
381 type Error = ConversionError;
382
383 fn try_from_val(env: &Env, v: &&[u8]) -> Result<Self, Self::Error> {
384 Ok(Bytes::from_slice(env, v))
385 }
386}
387
388impl<const N: usize> TryFromVal<Env, [u8; N]> for Bytes {
389 type Error = ConversionError;
390
391 fn try_from_val(env: &Env, v: &[u8; N]) -> Result<Self, Self::Error> {
392 Ok(Bytes::from_array(env, v))
393 }
394}
395
396impl Bytes {
397 #[inline(always)]
398 pub(crate) unsafe fn unchecked_new(env: Env, obj: BytesObject) -> Self {
399 Self { env, obj }
400 }
401
402 #[inline(always)]
403 pub fn env(&self) -> &Env {
404 &self.env
405 }
406
407 pub fn as_val(&self) -> &Val {
408 self.obj.as_val()
409 }
410
411 pub fn to_val(&self) -> Val {
412 self.obj.to_val()
413 }
414
415 pub fn as_object(&self) -> &BytesObject {
416 &self.obj
417 }
418
419 pub fn to_object(&self) -> BytesObject {
420 self.obj
421 }
422}
423
424impl Bytes {
425 #[inline(always)]
427 pub fn new(env: &Env) -> Bytes {
428 let obj = env.bytes_new().unwrap_infallible();
429 unsafe { Self::unchecked_new(env.clone(), obj) }
430 }
431
432 #[inline(always)]
434 pub fn from_array<const N: usize>(env: &Env, items: &[u8; N]) -> Bytes {
435 Self::from_slice(env, items)
436 }
437
438 #[inline(always)]
440 pub fn from_slice(env: &Env, items: &[u8]) -> Bytes {
441 Bytes {
442 env: env.clone(),
443 obj: env.bytes_new_from_slice(items).unwrap_optimized(),
444 }
445 }
446
447 #[inline(always)]
453 pub fn set(&mut self, i: u32, v: u8) {
454 let v32: u32 = v.into();
455 self.obj = self
456 .env()
457 .bytes_put(self.obj, i.into(), v32.into())
458 .unwrap_infallible()
459 }
460
461 #[inline(always)]
463 pub fn get(&self, i: u32) -> Option<u8> {
464 if i < self.len() {
465 Some(self.get_unchecked(i))
466 } else {
467 None
468 }
469 }
470
471 #[inline(always)]
477 pub fn get_unchecked(&self, i: u32) -> u8 {
478 let res32_val = self.env().bytes_get(self.obj, i.into()).unwrap_infallible();
479 let res32: u32 = res32_val.into();
480 res32 as u8
481 }
482
483 #[inline(always)]
485 pub fn is_empty(&self) -> bool {
486 self.len() == 0
487 }
488
489 #[inline(always)]
491 pub fn len(&self) -> u32 {
492 self.env().bytes_len(self.obj).unwrap_infallible().into()
493 }
494
495 #[inline(always)]
497 pub fn first(&self) -> Option<u8> {
498 if !self.is_empty() {
499 Some(self.first_unchecked())
500 } else {
501 None
502 }
503 }
504
505 #[inline(always)]
511 pub fn first_unchecked(&self) -> u8 {
512 let res: u32 = self.env().bytes_front(self.obj).unwrap_infallible().into();
513 res as u8
514 }
515
516 #[inline(always)]
518 pub fn last(&self) -> Option<u8> {
519 if !self.is_empty() {
520 Some(self.last_unchecked())
521 } else {
522 None
523 }
524 }
525
526 #[inline(always)]
532 pub fn last_unchecked(&self) -> u8 {
533 let res: u32 = self.env().bytes_back(self.obj).unwrap_infallible().into();
534 res as u8
535 }
536
537 #[inline(always)]
541 pub fn remove(&mut self, i: u32) -> Option<()> {
542 if i < self.len() {
543 self.remove_unchecked(i);
544 Some(())
545 } else {
546 None
547 }
548 }
549
550 #[inline(always)]
556 pub fn remove_unchecked(&mut self, i: u32) {
557 self.obj = self.env().bytes_del(self.obj, i.into()).unwrap_infallible()
558 }
559
560 #[inline(always)]
564 pub fn push_back(&mut self, x: u8) {
565 let x32: u32 = x.into();
566 self.obj = self
567 .env()
568 .bytes_push(self.obj, x32.into())
569 .unwrap_infallible()
570 }
571
572 #[inline(always)]
574 pub fn pop_back(&mut self) -> Option<u8> {
575 let last = self.last()?;
576 self.obj = self.env().bytes_pop(self.obj).unwrap_infallible();
577 Some(last)
578 }
579
580 #[inline(always)]
586 pub fn pop_back_unchecked(&mut self) -> u8 {
587 let last = self.last_unchecked();
588 self.obj = self.env().bytes_pop(self.obj).unwrap_infallible();
589 last
590 }
591
592 #[inline(always)]
598 pub fn insert(&mut self, i: u32, b: u8) {
599 let b32: u32 = b.into();
600 self.obj = self
601 .env()
602 .bytes_insert(self.obj, i.into(), b32.into())
603 .unwrap_infallible()
604 }
605
606 #[inline(always)]
612 pub fn insert_from_bytes(&mut self, i: u32, bytes: Bytes) {
613 let mut result = self.slice(..i);
614 result.append(&bytes);
615 result.append(&self.slice(i..));
616 *self = result
617 }
618
619 #[inline(always)]
625 pub fn insert_from_array<const N: usize>(&mut self, i: u32, array: &[u8; N]) {
626 self.insert_from_slice(i, array)
627 }
628
629 #[inline(always)]
635 pub fn insert_from_slice(&mut self, i: u32, slice: &[u8]) {
636 self.insert_from_bytes(i, Bytes::from_slice(self.env(), slice))
637 }
638
639 #[inline(always)]
641 pub fn append(&mut self, other: &Bytes) {
642 self.obj = self
643 .env()
644 .bytes_append(self.obj, other.obj)
645 .unwrap_infallible()
646 }
647
648 #[inline(always)]
650 pub fn extend_from_array<const N: usize>(&mut self, array: &[u8; N]) {
651 self.extend_from_slice(array)
652 }
653
654 #[inline(always)]
656 pub fn extend_from_slice(&mut self, slice: &[u8]) {
657 self.obj = self
658 .env()
659 .bytes_copy_from_slice(self.to_object(), self.len().into(), slice)
660 .unwrap_optimized()
661 }
662
663 #[inline(always)]
668 pub fn copy_from_slice(&mut self, i: u32, slice: &[u8]) {
669 self.obj = self
670 .env()
671 .bytes_copy_from_slice(self.to_object(), i.into(), slice)
672 .unwrap_optimized()
673 }
674
675 #[inline(always)]
681 pub fn copy_into_slice(&self, slice: &mut [u8]) {
682 let env = self.env();
683 if self.len() as usize != slice.len() {
684 sdk_panic!("Bytes::copy_into_slice with mismatched slice length")
685 }
686 env.bytes_copy_to_slice(self.to_object(), Val::U32_ZERO, slice)
687 .unwrap_optimized();
688 }
689
690 #[must_use]
697 pub fn slice(&self, r: impl RangeBounds<u32>) -> Self {
698 let start_bound = match r.start_bound() {
699 Bound::Included(s) => *s,
700 Bound::Excluded(s) => *s + 1,
701 Bound::Unbounded => 0,
702 };
703 let end_bound = match r.end_bound() {
704 Bound::Included(s) => *s + 1,
705 Bound::Excluded(s) => *s,
706 Bound::Unbounded => self.len(),
707 };
708 let env = self.env();
709 let bin = env
710 .bytes_slice(self.obj, start_bound.into(), end_bound.into())
711 .unwrap_infallible();
712 unsafe { Self::unchecked_new(env.clone(), bin) }
713 }
714
715 pub fn iter(&self) -> BytesIter {
716 self.clone().into_iter()
717 }
718
719 #[must_use]
733 pub fn to_buffer<const B: usize>(&self) -> BytesBuffer<B> {
734 let mut buffer = [0u8; B];
735 let len = self.len() as usize;
736 {
737 let slice = &mut buffer[0..len];
738 self.copy_into_slice(slice);
739 }
740 BytesBuffer { buffer, len }
741 }
742
743 #[cfg(feature = "alloc")]
750 #[must_use]
751 pub fn to_alloc_vec(&self) -> alloc::vec::Vec<u8> {
752 let len = self.len() as usize;
753 let mut vec = alloc::vec::from_elem(0u8, len);
754 self.copy_into_slice(&mut vec);
755 vec
756 }
757}
758
759#[derive(Debug, Clone, PartialEq, Eq)]
765pub struct BytesBuffer<const B: usize> {
766 buffer: [u8; B],
767 len: usize,
768}
769
770impl<const B: usize> Borrow<[u8]> for BytesBuffer<B> {
771 fn borrow(&self) -> &[u8] {
773 self.as_slice()
774 }
775}
776
777impl<const B: usize> BytesBuffer<B> {
778 pub fn as_slice(&self) -> &[u8] {
780 &self.buffer[..self.len]
781 }
782}
783
784impl IntoIterator for Bytes {
785 type Item = u8;
786 type IntoIter = BytesIter;
787
788 fn into_iter(self) -> Self::IntoIter {
789 BytesIter(self)
790 }
791}
792
793#[derive(Clone)]
794pub struct BytesIter(Bytes);
795
796impl BytesIter {
797 fn into_bin(self) -> Bytes {
798 self.0
799 }
800}
801
802impl Iterator for BytesIter {
803 type Item = u8;
804
805 fn next(&mut self) -> Option<Self::Item> {
806 if self.0.is_empty() {
807 None
808 } else {
809 let val: u32 = self
810 .0
811 .env()
812 .bytes_front(self.0.obj)
813 .unwrap_infallible()
814 .into();
815 self.0 = self.0.slice(1..);
816 Some(val as u8)
817 }
818 }
819
820 fn size_hint(&self) -> (usize, Option<usize>) {
821 let len = self.0.len() as usize;
822 (len, Some(len))
823 }
824}
825
826impl DoubleEndedIterator for BytesIter {
827 fn next_back(&mut self) -> Option<Self::Item> {
828 let len = self.0.len();
829 if len == 0 {
830 None
831 } else {
832 let val: u32 = self
833 .0
834 .env()
835 .bytes_back(self.0.obj)
836 .unwrap_infallible()
837 .into();
838 self.0 = self.0.slice(..len - 1);
839 Some(val as u8)
840 }
841 }
842}
843
844impl FusedIterator for BytesIter {}
845
846impl ExactSizeIterator for BytesIter {
847 fn len(&self) -> usize {
848 self.0.len() as usize
849 }
850}
851
852#[derive(Clone)]
881#[repr(transparent)]
882pub struct BytesN<const N: usize>(Bytes);
883
884impl<const N: usize> Debug for BytesN<N> {
885 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
886 write!(f, "BytesN<{}>(", N)?;
887 let mut iter = self.iter();
888 if let Some(x) = iter.next() {
889 write!(f, "{:?}", x)?;
890 }
891 for x in iter {
892 write!(f, ", {:?}", x)?;
893 }
894 write!(f, ")")?;
895 Ok(())
896 }
897}
898
899impl<const N: usize> Eq for BytesN<N> {}
900
901impl<const N: usize> PartialEq for BytesN<N> {
902 fn eq(&self, other: &Self) -> bool {
903 self.partial_cmp(other) == Some(Ordering::Equal)
904 }
905}
906
907impl<const N: usize> PartialEq<[u8; N]> for BytesN<N> {
908 fn eq(&self, other: &[u8; N]) -> bool {
909 let other: BytesN<N> = other.into_val(self.env());
910 self.eq(&other)
911 }
912}
913
914impl<const N: usize> PartialEq<BytesN<N>> for [u8; N] {
915 fn eq(&self, other: &BytesN<N>) -> bool {
916 let self_: BytesN<N> = self.into_val(other.env());
917 self_.eq(other)
918 }
919}
920
921impl<const N: usize> PartialOrd for BytesN<N> {
922 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
923 Some(Ord::cmp(self, other))
924 }
925}
926
927impl<const N: usize> PartialOrd<[u8; N]> for BytesN<N> {
928 fn partial_cmp(&self, other: &[u8; N]) -> Option<Ordering> {
929 let other: BytesN<N> = other.into_val(self.env());
930 self.partial_cmp(&other)
931 }
932}
933
934impl<const N: usize> PartialOrd<BytesN<N>> for [u8; N] {
935 fn partial_cmp(&self, other: &BytesN<N>) -> Option<Ordering> {
936 let self_: BytesN<N> = self.into_val(other.env());
937 self_.partial_cmp(other)
938 }
939}
940
941impl<const N: usize> Ord for BytesN<N> {
942 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
943 self.0.cmp(&other.0)
944 }
945}
946
947impl<const N: usize> Borrow<Bytes> for BytesN<N> {
948 fn borrow(&self) -> &Bytes {
949 &self.0
950 }
951}
952
953impl<const N: usize> Borrow<Bytes> for &BytesN<N> {
954 fn borrow(&self) -> &Bytes {
955 &self.0
956 }
957}
958
959impl<const N: usize> Borrow<Bytes> for &mut BytesN<N> {
960 fn borrow(&self) -> &Bytes {
961 &self.0
962 }
963}
964
965impl<const N: usize> AsRef<Bytes> for BytesN<N> {
966 fn as_ref(&self) -> &Bytes {
967 &self.0
968 }
969}
970
971impl<const N: usize> TryFromVal<Env, BytesN<N>> for BytesN<N> {
972 type Error = ConversionError;
973
974 fn try_from_val(_env: &Env, v: &BytesN<N>) -> Result<Self, Self::Error> {
975 Ok(v.clone())
976 }
977}
978
979impl<const N: usize> TryFromVal<Env, BytesN<N>> for Bytes {
980 type Error = ConversionError;
981
982 fn try_from_val(_env: &Env, v: &BytesN<N>) -> Result<Self, Self::Error> {
983 Ok(v.0.clone())
984 }
985}
986
987impl<const N: usize> TryFromVal<Env, [u8; N]> for BytesN<N> {
988 type Error = ConversionError;
989
990 fn try_from_val(env: &Env, v: &[u8; N]) -> Result<Self, Self::Error> {
991 Ok(BytesN::from_array(env, v))
992 }
993}
994
995impl<const N: usize> TryFromVal<Env, BytesN<N>> for [u8; N] {
996 type Error = ConversionError;
997
998 fn try_from_val(_env: &Env, v: &BytesN<N>) -> Result<Self, Self::Error> {
999 Ok(v.to_array())
1000 }
1001}
1002
1003impl<const N: usize> TryFromVal<Env, BytesObject> for BytesN<N> {
1004 type Error = ConversionError;
1005
1006 fn try_from_val(env: &Env, obj: &BytesObject) -> Result<Self, Self::Error> {
1007 Bytes::try_from_val(env, obj).unwrap_infallible().try_into()
1008 }
1009}
1010
1011impl<const N: usize> TryFromVal<Env, Val> for BytesN<N> {
1012 type Error = ConversionError;
1013
1014 fn try_from_val(env: &Env, val: &Val) -> Result<Self, Self::Error> {
1015 Bytes::try_from_val(env, val)?.try_into()
1016 }
1017}
1018
1019impl<const N: usize> TryFromVal<Env, BytesN<N>> for Val {
1020 type Error = ConversionError;
1021
1022 fn try_from_val(_env: &Env, v: &BytesN<N>) -> Result<Self, Self::Error> {
1023 Ok(v.to_val())
1024 }
1025}
1026
1027impl<const N: usize> TryFromVal<Env, &BytesN<N>> for Val {
1028 type Error = ConversionError;
1029
1030 fn try_from_val(_env: &Env, v: &&BytesN<N>) -> Result<Self, Self::Error> {
1031 Ok(v.to_val())
1032 }
1033}
1034
1035impl<const N: usize> TryFrom<Bytes> for BytesN<N> {
1036 type Error = ConversionError;
1037
1038 #[inline(always)]
1039 fn try_from(bin: Bytes) -> Result<Self, Self::Error> {
1040 if bin.len() == { N as u32 } {
1041 Ok(Self(bin))
1042 } else {
1043 Err(ConversionError {})
1044 }
1045 }
1046}
1047
1048impl<const N: usize> TryFrom<&Bytes> for BytesN<N> {
1049 type Error = ConversionError;
1050
1051 #[inline(always)]
1052 fn try_from(bin: &Bytes) -> Result<Self, Self::Error> {
1053 bin.clone().try_into()
1054 }
1055}
1056
1057impl<const N: usize> From<BytesN<N>> for Val {
1058 #[inline(always)]
1059 fn from(v: BytesN<N>) -> Self {
1060 v.0.into()
1061 }
1062}
1063
1064impl<const N: usize> From<BytesN<N>> for Bytes {
1065 #[inline(always)]
1066 fn from(v: BytesN<N>) -> Self {
1067 v.0
1068 }
1069}
1070
1071impl<const N: usize> From<&BytesN<N>> for Bytes {
1072 #[inline(always)]
1073 fn from(v: &BytesN<N>) -> Self {
1074 v.0.clone()
1075 }
1076}
1077
1078#[cfg(not(target_family = "wasm"))]
1079impl<const N: usize> TryFrom<&BytesN<N>> for ScVal {
1080 type Error = ConversionError;
1081 fn try_from(v: &BytesN<N>) -> Result<Self, ConversionError> {
1082 Ok(ScVal::try_from_val(&v.0.env, &v.0.obj.to_val())?)
1083 }
1084}
1085
1086#[cfg(not(target_family = "wasm"))]
1087impl<const N: usize> TryFrom<BytesN<N>> for ScVal {
1088 type Error = ConversionError;
1089 fn try_from(v: BytesN<N>) -> Result<Self, ConversionError> {
1090 (&v).try_into()
1091 }
1092}
1093
1094#[cfg(not(target_family = "wasm"))]
1095impl<const N: usize> TryFromVal<Env, ScVal> for BytesN<N> {
1096 type Error = ConversionError;
1097 fn try_from_val(env: &Env, val: &ScVal) -> Result<Self, Self::Error> {
1098 Bytes::try_from_val(env, val)?.try_into()
1099 }
1100}
1101
1102impl<const N: usize> BytesN<N> {
1103 #[inline(always)]
1104 pub(crate) unsafe fn unchecked_new(env: Env, obj: BytesObject) -> Self {
1105 Self(Bytes::unchecked_new(env, obj))
1106 }
1107
1108 pub fn env(&self) -> &Env {
1109 self.0.env()
1110 }
1111
1112 pub fn as_val(&self) -> &Val {
1113 self.0.as_val()
1114 }
1115
1116 pub fn to_val(&self) -> Val {
1117 self.0.to_val()
1118 }
1119
1120 pub fn as_object(&self) -> &BytesObject {
1121 self.0.as_object()
1122 }
1123
1124 pub fn to_object(&self) -> BytesObject {
1125 self.0.to_object()
1126 }
1127
1128 #[inline(always)]
1130 pub fn from_array(env: &Env, items: &[u8; N]) -> BytesN<N> {
1131 BytesN(Bytes::from_slice(env, items))
1132 }
1133
1134 #[inline(always)]
1140 pub fn set(&mut self, i: u32, v: u8) {
1141 self.0.set(i, v);
1142 }
1143
1144 #[inline(always)]
1146 pub fn get(&self, i: u32) -> Option<u8> {
1147 self.0.get(i)
1148 }
1149
1150 #[inline(always)]
1156 pub fn get_unchecked(&self, i: u32) -> u8 {
1157 self.0.get_unchecked(i)
1158 }
1159
1160 #[inline(always)]
1162 pub fn is_empty(&self) -> bool {
1163 false
1164 }
1165
1166 #[inline(always)]
1168 pub fn len(&self) -> u32 {
1169 N as u32
1170 }
1171
1172 #[inline(always)]
1174 pub fn first(&self) -> Option<u8> {
1175 self.0.first()
1176 }
1177
1178 #[inline(always)]
1184 pub fn first_unchecked(&self) -> u8 {
1185 self.0.first_unchecked()
1186 }
1187
1188 #[inline(always)]
1190 pub fn last(&self) -> Option<u8> {
1191 self.0.last()
1192 }
1193
1194 #[inline(always)]
1200 pub fn last_unchecked(&self) -> u8 {
1201 self.0.last_unchecked()
1202 }
1203
1204 #[inline(always)]
1206 pub fn copy_into_slice(&self, slice: &mut [u8; N]) {
1207 let env = self.env();
1208 env.bytes_copy_to_slice(self.to_object(), Val::U32_ZERO, slice)
1209 .unwrap_optimized();
1210 }
1211
1212 #[inline(always)]
1214 pub fn to_array(&self) -> [u8; N] {
1215 let mut array = [0u8; N];
1216 self.copy_into_slice(&mut array);
1217 array
1218 }
1219
1220 pub fn iter(&self) -> BytesIter {
1221 self.clone().into_iter()
1222 }
1223}
1224
1225#[cfg(any(test, feature = "testutils"))]
1226#[cfg_attr(feature = "docs", doc(cfg(feature = "testutils")))]
1227impl<const N: usize> crate::testutils::BytesN<N> for BytesN<N> {
1228 fn random(env: &Env) -> BytesN<N> {
1229 BytesN::from_array(env, &crate::testutils::random())
1230 }
1231}
1232
1233impl<const N: usize> IntoIterator for BytesN<N> {
1234 type Item = u8;
1235
1236 type IntoIter = BytesIter;
1237
1238 fn into_iter(self) -> Self::IntoIter {
1239 BytesIter(self.0)
1240 }
1241}
1242
1243impl<const N: usize> TryFrom<Bytes> for [u8; N] {
1244 type Error = ConversionError;
1245
1246 fn try_from(bin: Bytes) -> Result<Self, Self::Error> {
1247 let fixed: BytesN<N> = bin.try_into()?;
1248 Ok(fixed.into())
1249 }
1250}
1251
1252impl<const N: usize> TryFrom<&Bytes> for [u8; N] {
1253 type Error = ConversionError;
1254
1255 fn try_from(bin: &Bytes) -> Result<Self, Self::Error> {
1256 let fixed: BytesN<N> = bin.try_into()?;
1257 Ok(fixed.into())
1258 }
1259}
1260
1261impl<const N: usize> From<BytesN<N>> for [u8; N] {
1262 fn from(bin: BytesN<N>) -> Self {
1263 let mut res = [0u8; N];
1264 for (i, b) in bin.into_iter().enumerate() {
1265 res[i] = b;
1266 }
1267 res
1268 }
1269}
1270
1271impl<const N: usize> From<&BytesN<N>> for [u8; N] {
1272 fn from(bin: &BytesN<N>) -> Self {
1273 let mut res = [0u8; N];
1274 for (i, b) in bin.iter().enumerate() {
1275 res[i] = b;
1276 }
1277 res
1278 }
1279}
1280
1281#[cfg(test)]
1282mod test {
1283 use super::*;
1284
1285 #[test]
1286 fn bytes_from_and_to_slices() {
1287 let env = Env::default();
1288
1289 let b = Bytes::from_slice(&env, &[1, 2, 3, 4]);
1290 let mut out = [0u8; 4];
1291 b.copy_into_slice(&mut out);
1292 assert_eq!([1, 2, 3, 4], out);
1293
1294 let mut b = Bytes::from_slice(&env, &[1, 2, 3, 4]);
1295 b.extend_from_slice(&[5, 6, 7, 8]);
1296 b.insert_from_slice(1, &[9, 10]);
1297 b.insert_from_bytes(4, Bytes::from_slice(&env, &[0, 0]));
1298 let mut out = [0u8; 12];
1299 b.copy_into_slice(&mut out);
1300 assert_eq!([1, 9, 10, 2, 0, 0, 3, 4, 5, 6, 7, 8], out);
1301 b.copy_from_slice(3, &[7, 6, 5]);
1302 b.copy_into_slice(&mut out);
1303 assert_eq!([1, 9, 10, 7, 6, 5, 3, 4, 5, 6, 7, 8], out);
1304 }
1305
1306 #[test]
1307 fn bytesn_from_and_to_slices() {
1308 let env = Env::default();
1309
1310 let b = BytesN::from_array(&env, &[1, 2, 3, 4]);
1311 let mut out = [0u8; 4];
1312 b.copy_into_slice(&mut out);
1313 assert_eq!([1, 2, 3, 4], out);
1314 }
1315
1316 #[test]
1317 #[should_panic]
1318 fn bytes_to_short_slice() {
1319 let env = Env::default();
1320 let b = Bytes::from_slice(&env, &[1, 2, 3, 4]);
1321 let mut out = [0u8; 3];
1322 b.copy_into_slice(&mut out);
1323 }
1324
1325 #[test]
1326 #[should_panic]
1327 fn bytes_to_long_slice() {
1328 let env = Env::default();
1329 let b = Bytes::from_slice(&env, &[1, 2, 3, 4]);
1330 let mut out = [0u8; 5];
1331 b.copy_into_slice(&mut out);
1332 }
1333
1334 #[test]
1335 fn macro_bytes() {
1336 let env = Env::default();
1337 assert_eq!(bytes!(&env), Bytes::new(&env));
1338 assert_eq!(bytes!(&env, 1), {
1339 let mut b = Bytes::new(&env);
1340 b.push_back(1);
1341 b
1342 });
1343 assert_eq!(bytes!(&env, 1,), {
1344 let mut b = Bytes::new(&env);
1345 b.push_back(1);
1346 b
1347 });
1348 assert_eq!(bytes!(&env, [3, 2, 1,]), {
1349 let mut b = Bytes::new(&env);
1350 b.push_back(3);
1351 b.push_back(2);
1352 b.push_back(1);
1353 b
1354 });
1355 }
1356
1357 #[test]
1358 fn macro_bytes_hex() {
1359 let env = Env::default();
1360 assert_eq!(bytes!(&env), Bytes::new(&env));
1361 assert_eq!(bytes!(&env, 1), {
1362 let mut b = Bytes::new(&env);
1363 b.push_back(1);
1364 b
1365 });
1366 assert_eq!(bytes!(&env, 1,), {
1367 let mut b = Bytes::new(&env);
1368 b.push_back(1);
1369 b
1370 });
1371 assert_eq!(bytes!(&env, 0x30201), {
1372 let mut b = Bytes::new(&env);
1373 b.push_back(3);
1374 b.push_back(2);
1375 b.push_back(1);
1376 b
1377 });
1378 assert_eq!(bytes!(&env, 0x0000030201), {
1379 Bytes::from_array(&env, &[0, 0, 3, 2, 1])
1380 });
1381 }
1382
1383 #[test]
1384 fn macro_bytesn() {
1385 let env = Env::default();
1386 assert_eq!(bytesn!(&env, 1), { BytesN::from_array(&env, &[1]) });
1387 assert_eq!(bytesn!(&env, 1,), { BytesN::from_array(&env, &[1]) });
1388 assert_eq!(bytesn!(&env, [3, 2, 1,]), {
1389 BytesN::from_array(&env, &[3, 2, 1])
1390 });
1391 }
1392
1393 #[test]
1394 fn macro_bytesn_hex() {
1395 let env = Env::default();
1396 assert_eq!(bytesn!(&env, 0x030201), {
1397 BytesN::from_array(&env, &[3, 2, 1])
1398 });
1399 assert_eq!(bytesn!(&env, 0x0000030201), {
1400 BytesN::from_array(&env, &[0, 0, 3, 2, 1])
1401 });
1402 }
1403
1404 #[test]
1405 fn test_bin() {
1406 let env = Env::default();
1407
1408 let mut bin = Bytes::new(&env);
1409 assert_eq!(bin.len(), 0);
1410 bin.push_back(10);
1411 assert_eq!(bin.len(), 1);
1412 bin.push_back(20);
1413 assert_eq!(bin.len(), 2);
1414 bin.push_back(30);
1415 assert_eq!(bin.len(), 3);
1416 println!("{:?}", bin);
1417
1418 let bin_ref = &bin;
1419 assert_eq!(bin_ref.len(), 3);
1420
1421 let mut bin_copy = bin.clone();
1422 assert!(bin == bin_copy);
1423 assert_eq!(bin_copy.len(), 3);
1424 bin_copy.push_back(40);
1425 assert_eq!(bin_copy.len(), 4);
1426 assert!(bin != bin_copy);
1427
1428 assert_eq!(bin.len(), 3);
1429 assert_eq!(bin_ref.len(), 3);
1430
1431 bin_copy.pop_back();
1432 assert!(bin == bin_copy);
1433
1434 let bad_fixed: Result<BytesN<4>, ConversionError> = bin.try_into();
1435 assert!(bad_fixed.is_err());
1436 let fixed: BytesN<3> = bin_copy.try_into().unwrap();
1437 println!("{:?}", fixed);
1438 }
1439
1440 #[test]
1441 fn test_bin_iter() {
1442 let env = Env::default();
1443 let mut bin = Bytes::new(&env);
1444 bin.push_back(10);
1445 bin.push_back(20);
1446 bin.push_back(30);
1447 let mut iter = bin.iter();
1448 assert_eq!(iter.next(), Some(10));
1449 assert_eq!(iter.next(), Some(20));
1450 assert_eq!(iter.next(), Some(30));
1451 assert_eq!(iter.next(), None);
1452 assert_eq!(iter.next(), None);
1453 let mut iter = bin.iter();
1454 assert_eq!(iter.next(), Some(10));
1455 assert_eq!(iter.next_back(), Some(30));
1456 assert_eq!(iter.next_back(), Some(20));
1457 assert_eq!(iter.next_back(), None);
1458 assert_eq!(iter.next_back(), None);
1459
1460 let fixed: BytesN<3> = bin.try_into().unwrap();
1461 let mut iter = fixed.iter();
1462 assert_eq!(iter.next(), Some(10));
1463 assert_eq!(iter.next(), Some(20));
1464 assert_eq!(iter.next(), Some(30));
1465 assert_eq!(iter.next(), None);
1466 assert_eq!(iter.next(), None);
1467 let mut iter = fixed.iter();
1468 assert_eq!(iter.next(), Some(10));
1469 assert_eq!(iter.next_back(), Some(30));
1470 assert_eq!(iter.next_back(), Some(20));
1471 assert_eq!(iter.next_back(), None);
1472 assert_eq!(iter.next_back(), None);
1473 }
1474
1475 #[test]
1476 fn test_array_binary_borrow() {
1477 fn get_len(b: impl Borrow<Bytes>) -> u32 {
1478 let b: &Bytes = b.borrow();
1479 b.len()
1480 }
1481
1482 let env = Env::default();
1483 let mut bin = Bytes::new(&env);
1484 bin.push_back(10);
1485 bin.push_back(20);
1486 bin.push_back(30);
1487 assert_eq!(bin.len(), 3);
1488
1489 let arr_bin: BytesN<3> = bin.clone().try_into().unwrap();
1490 assert_eq!(arr_bin.len(), 3);
1491
1492 assert_eq!(get_len(&bin), 3);
1493 assert_eq!(get_len(bin), 3);
1494 assert_eq!(get_len(&arr_bin), 3);
1495 assert_eq!(get_len(arr_bin), 3);
1496 }
1497
1498 #[test]
1499 fn bytesn_debug() {
1500 let env = Env::default();
1501 let mut bin = Bytes::new(&env);
1502 bin.push_back(10);
1503 bin.push_back(20);
1504 bin.push_back(30);
1505 let arr_bin: BytesN<3> = bin.clone().try_into().unwrap();
1506 assert_eq!(format!("{:?}", arr_bin), "BytesN<3>(10, 20, 30)");
1507 }
1508
1509 #[test]
1510 fn test_is_empty() {
1511 let env = Env::default();
1512 let mut bin = Bytes::new(&env);
1513 assert_eq!(bin.is_empty(), true);
1514 bin.push_back(10);
1515 assert_eq!(bin.is_empty(), false);
1516 }
1517
1518 #[test]
1519 fn test_first() {
1520 let env = Env::default();
1521 let mut bin = bytes![&env, [1, 2, 3, 4]];
1522
1523 assert_eq!(bin.first(), Some(1));
1524 bin.remove(0);
1525 assert_eq!(bin.first(), Some(2));
1526
1527 let bin = bytes![&env];
1529 assert_eq!(bin.first(), None);
1530 }
1531
1532 #[test]
1533 fn test_first_unchecked() {
1534 let env = Env::default();
1535 let mut bin = bytes![&env, [1, 2, 3, 4]];
1536
1537 assert_eq!(bin.first_unchecked(), 1);
1538 bin.remove(0);
1539 assert_eq!(bin.first_unchecked(), 2);
1540 }
1541
1542 #[test]
1543 #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1544 fn test_first_unchecked_panics() {
1545 let env = Env::default();
1546 let bin = bytes![&env];
1547 bin.first_unchecked();
1548 }
1549
1550 #[test]
1551 fn test_last() {
1552 let env = Env::default();
1553 let mut bin = bytes![&env, [1, 2, 3, 4]];
1554
1555 assert_eq!(bin.last(), Some(4));
1556 bin.remove(3);
1557 assert_eq!(bin.last(), Some(3));
1558
1559 let bin = bytes![&env];
1561 assert_eq!(bin.last(), None);
1562 }
1563
1564 #[test]
1565 fn test_last_unchecked() {
1566 let env = Env::default();
1567 let mut bin = bytes![&env, [1, 2, 3, 4]];
1568
1569 assert_eq!(bin.last_unchecked(), 4);
1570 bin.remove(3);
1571 assert_eq!(bin.last_unchecked(), 3);
1572 }
1573
1574 #[test]
1575 #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1576 fn test_last_unchecked_panics() {
1577 let env = Env::default();
1578 let bin = bytes![&env];
1579 bin.last_unchecked();
1580 }
1581
1582 #[test]
1583 fn test_get() {
1584 let env = Env::default();
1585 let bin = bytes![&env, [0, 1, 5, 2, 8]];
1586
1587 assert_eq!(bin.get(0), Some(0));
1588 assert_eq!(bin.get(1), Some(1));
1589 assert_eq!(bin.get(2), Some(5));
1590 assert_eq!(bin.get(3), Some(2));
1591 assert_eq!(bin.get(4), Some(8));
1592
1593 assert_eq!(bin.get(bin.len()), None);
1594 assert_eq!(bin.get(bin.len() + 1), None);
1595 assert_eq!(bin.get(u32::MAX), None);
1596
1597 let bin = bytes![&env];
1599 assert_eq!(bin.get(0), None);
1600 assert_eq!(bin.get(bin.len()), None);
1601 assert_eq!(bin.get(bin.len() + 1), None);
1602 assert_eq!(bin.get(u32::MAX), None);
1603 }
1604
1605 #[test]
1606 fn test_get_unchecked() {
1607 let env = Env::default();
1608 let bin = bytes![&env, [0, 1, 5, 2, 8]];
1609
1610 assert_eq!(bin.get_unchecked(0), 0);
1611 assert_eq!(bin.get_unchecked(1), 1);
1612 assert_eq!(bin.get_unchecked(2), 5);
1613 assert_eq!(bin.get_unchecked(3), 2);
1614 assert_eq!(bin.get_unchecked(4), 8);
1615 }
1616
1617 #[test]
1618 #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1619 fn test_get_unchecked_panics() {
1620 let env = Env::default();
1621 let bin = bytes![&env];
1622 bin.get_unchecked(0);
1623 }
1624
1625 #[test]
1626 fn test_remove() {
1627 let env = Env::default();
1628 let mut bin = bytes![&env, [1, 2, 3, 4]];
1629
1630 assert_eq!(bin.remove(2), Some(()));
1631 assert_eq!(bin, bytes![&env, [1, 2, 4]]);
1632 assert_eq!(bin.len(), 3);
1633
1634 assert_eq!(bin.remove(bin.len()), None);
1636 assert_eq!(bin.remove(bin.len() + 1), None);
1637 assert_eq!(bin.remove(u32::MAX), None);
1638
1639 assert_eq!(bin.remove(0), Some(()));
1641 assert_eq!(bin.remove(0), Some(()));
1642 assert_eq!(bin.remove(0), Some(()));
1643 assert_eq!(bin, bytes![&env]);
1644 assert_eq!(bin.len(), 0);
1645
1646 let mut bin = bytes![&env];
1648 assert_eq!(bin.remove(0), None);
1649 assert_eq!(bin.remove(bin.len()), None);
1650 assert_eq!(bin.remove(bin.len() + 1), None);
1651 assert_eq!(bin.remove(u32::MAX), None);
1652 }
1653
1654 #[test]
1655 fn test_remove_unchecked() {
1656 let env = Env::default();
1657 let mut bin = bytes![&env, [1, 2, 3, 4]];
1658
1659 bin.remove_unchecked(2);
1660 assert_eq!(bin, bytes![&env, [1, 2, 4]]);
1661 assert_eq!(bin.len(), 3);
1662 }
1663
1664 #[test]
1665 #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1666 fn test_remove_unchecked_panics() {
1667 let env = Env::default();
1668 let mut bin = bytes![&env, [1, 2, 3, 4]];
1669 bin.remove_unchecked(bin.len());
1670 }
1671
1672 #[test]
1673 fn test_pop() {
1674 let env = Env::default();
1675 let mut bin = bytes![&env, [0, 1, 2, 3, 4]];
1676
1677 assert_eq!(bin.pop_back(), Some(4));
1678 assert_eq!(bin.pop_back(), Some(3));
1679 assert_eq!(bin.len(), 3);
1680 assert_eq!(bin, bytes![&env, [0, 1, 2]]);
1681
1682 let mut bin = bytes![&env];
1684 assert_eq!(bin.pop_back(), None);
1685 }
1686
1687 #[test]
1688 fn test_pop_unchecked() {
1689 let env = Env::default();
1690 let mut bin = bytes![&env, [0, 1, 2, 3, 4]];
1691
1692 assert_eq!(bin.pop_back_unchecked(), 4);
1693 assert_eq!(bin.pop_back_unchecked(), 3);
1694 assert_eq!(bin.len(), 3);
1695 assert_eq!(bin, bytes![&env, [0, 1, 2]]);
1696 }
1697
1698 #[test]
1699 #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1700 fn test_pop_unchecked_panics() {
1701 let env = Env::default();
1702 let mut bin = bytes![&env];
1703 bin.pop_back_unchecked();
1704 }
1705
1706 #[test]
1707 fn test_insert() {
1708 let env = Env::default();
1709 let mut bin = bytes![&env, [0, 1, 2, 3, 4]];
1710
1711 bin.insert(3, 42);
1712 assert_eq!(bin, bytes![&env, [0, 1, 2, 42, 3, 4]]);
1713
1714 bin.insert(0, 43);
1716 assert_eq!(bin, bytes![&env, [43, 0, 1, 2, 42, 3, 4]]);
1717
1718 bin.insert(bin.len(), 44);
1720 assert_eq!(bin, bytes![&env, [43, 0, 1, 2, 42, 3, 4, 44]]);
1721 }
1722
1723 #[test]
1724 #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1725 fn test_insert_panic() {
1726 let env = Env::default();
1727 let mut bin = bytes![&env, [0, 1, 2, 3, 4]];
1728 bin.insert(80, 44);
1729 }
1730
1731 #[test]
1732 fn test_slice() {
1733 let env = Env::default();
1734 let bin = bytes![&env, [0, 1, 2, 3, 4]];
1735
1736 let bin2 = bin.slice(2..);
1737 assert_eq!(bin2, bytes![&env, [2, 3, 4]]);
1738
1739 let bin3 = bin.slice(3..3);
1740 assert_eq!(bin3, bytes![&env]);
1741
1742 let bin4 = bin.slice(0..3);
1743 assert_eq!(bin4, bytes![&env, [0, 1, 2]]);
1744
1745 let bin4 = bin.slice(3..5);
1746 assert_eq!(bin4, bytes![&env, [3, 4]]);
1747
1748 assert_eq!(bin, bytes![&env, [0, 1, 2, 3, 4]]); }
1750
1751 #[test]
1752 #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1753 fn test_slice_panic() {
1754 let env = Env::default();
1755 let bin = bytes![&env, [0, 1, 2, 3, 4]];
1756 let _ = bin.slice(..=bin.len());
1757 }
1758}