1use super::{
2 Int128Parts, ScBytes, ScError, ScMap, ScMapEntry, ScSymbol, ScVal, ScVec, UInt128Parts,
3};
4
5#[cfg(all(not(feature = "std"), feature = "alloc"))]
6extern crate alloc;
7#[cfg(all(not(feature = "std"), feature = "alloc"))]
8use alloc::{string::String, vec, vec::Vec};
9
10impl From<ScError> for ScVal {
13 fn from(v: ScError) -> Self {
14 ScVal::Error(v)
15 }
16}
17
18impl TryFrom<ScVal> for ScError {
19 type Error = ();
20 fn try_from(v: ScVal) -> Result<Self, Self::Error> {
21 if let ScVal::Error(s) = v {
22 Ok(s)
23 } else {
24 Err(())
25 }
26 }
27}
28
29impl From<i32> for ScVal {
30 fn from(v: i32) -> ScVal {
31 ScVal::I32(v)
32 }
33}
34
35impl From<&i32> for ScVal {
36 fn from(v: &i32) -> ScVal {
37 ScVal::I32(*v)
38 }
39}
40
41impl TryFrom<ScVal> for i32 {
42 type Error = ();
43 fn try_from(v: ScVal) -> Result<Self, Self::Error> {
44 if let ScVal::I32(i) = v {
45 Ok(i)
46 } else {
47 Err(())
48 }
49 }
50}
51
52impl From<u32> for ScVal {
53 fn from(v: u32) -> ScVal {
54 ScVal::U32(v)
55 }
56}
57
58impl From<&u32> for ScVal {
59 fn from(v: &u32) -> ScVal {
60 ScVal::U32(*v)
61 }
62}
63
64impl TryFrom<ScVal> for u32 {
65 type Error = ();
66 fn try_from(v: ScVal) -> Result<Self, Self::Error> {
67 if let ScVal::U32(i) = v {
68 Ok(i)
69 } else {
70 Err(())
71 }
72 }
73}
74
75impl From<i64> for ScVal {
76 fn from(v: i64) -> ScVal {
77 ScVal::I64(v)
78 }
79}
80
81impl From<&i64> for ScVal {
82 fn from(v: &i64) -> ScVal {
83 <_ as Into<ScVal>>::into(*v)
84 }
85}
86
87impl TryFrom<ScVal> for i64 {
88 type Error = ();
89 fn try_from(v: ScVal) -> Result<Self, Self::Error> {
90 if let ScVal::I64(i) = v {
91 Ok(i)
92 } else {
93 Err(())
94 }
95 }
96}
97
98impl From<()> for ScVal {
99 fn from((): ()) -> Self {
100 ScVal::Void
101 }
102}
103
104impl From<&()> for ScVal {
105 fn from((): &()) -> Self {
106 ScVal::Void
107 }
108}
109
110impl TryFrom<ScVal> for () {
111 type Error = ();
112 fn try_from(v: ScVal) -> Result<Self, Self::Error> {
113 if let ScVal::Void = v {
114 Ok(())
115 } else {
116 Err(())
117 }
118 }
119}
120
121impl From<bool> for ScVal {
122 fn from(v: bool) -> Self {
123 ScVal::Bool(v)
124 }
125}
126
127impl From<&bool> for ScVal {
128 fn from(v: &bool) -> Self {
129 <_ as Into<ScVal>>::into(*v)
130 }
131}
132
133impl TryFrom<ScVal> for bool {
134 type Error = ();
135 fn try_from(v: ScVal) -> Result<Self, Self::Error> {
136 if let ScVal::Bool(b) = v {
137 Ok(b)
138 } else {
139 Err(())
140 }
141 }
142}
143
144impl From<u64> for ScVal {
145 fn from(v: u64) -> Self {
146 ScVal::U64(v)
147 }
148}
149
150impl From<&u64> for ScVal {
151 fn from(v: &u64) -> Self {
152 ScVal::U64(*v)
153 }
154}
155
156impl TryFrom<ScVal> for u64 {
157 type Error = ();
158 fn try_from(v: ScVal) -> Result<Self, Self::Error> {
159 if let ScVal::U64(i) = v {
160 Ok(i)
161 } else {
162 Err(())
163 }
164 }
165}
166
167pub mod int128_helpers {
168 #[must_use]
169 #[inline(always)]
170 #[allow(clippy::inline_always, clippy::cast_possible_truncation)]
171 pub fn u128_hi(u: u128) -> u64 {
172 (u >> 64) as u64
173 }
174
175 #[must_use]
176 #[inline(always)]
177 #[allow(clippy::inline_always, clippy::cast_possible_truncation)]
178 pub fn u128_lo(u: u128) -> u64 {
179 u as u64
180 }
181
182 #[must_use]
183 #[inline(always)]
184 #[allow(clippy::inline_always)]
185 pub fn u128_from_pieces(hi: u64, lo: u64) -> u128 {
186 (u128::from(hi) << 64) | u128::from(lo)
187 }
188
189 #[must_use]
190 #[inline(always)]
191 #[allow(clippy::inline_always, clippy::cast_possible_truncation)]
192 pub fn i128_hi(i: i128) -> i64 {
193 (i >> 64) as i64
194 }
195
196 #[must_use]
197 #[inline(always)]
198 #[allow(
199 clippy::inline_always,
200 clippy::cast_possible_truncation,
201 clippy::cast_sign_loss
202 )]
203 pub fn i128_lo(i: i128) -> u64 {
204 i as u64
205 }
206
207 #[must_use]
208 #[inline(always)]
209 #[allow(
210 clippy::inline_always,
211 clippy::cast_sign_loss,
212 clippy::cast_possible_wrap
213 )]
214 pub fn i128_from_pieces(hi: i64, lo: u64) -> i128 {
215 (u128::from(hi as u64) << 64 | u128::from(lo)) as i128
216 }
217}
218
219#[allow(clippy::wildcard_imports)]
220use int128_helpers::*;
221
222impl From<u128> for ScVal {
223 fn from(v: u128) -> Self {
224 ScVal::U128(UInt128Parts {
225 hi: u128_hi(v),
226 lo: u128_lo(v),
227 })
228 }
229}
230
231impl From<&u128> for ScVal {
232 fn from(v: &u128) -> Self {
233 <ScVal as From<u128>>::from(*v)
234 }
235}
236
237impl From<&UInt128Parts> for u128 {
238 fn from(v: &UInt128Parts) -> Self {
239 u128_from_pieces(v.hi, v.lo)
240 }
241}
242
243impl TryFrom<ScVal> for u128 {
244 type Error = ();
245 fn try_from(v: ScVal) -> Result<Self, Self::Error> {
246 if let ScVal::U128(i) = v {
247 Ok((&i).into())
248 } else {
249 Err(())
250 }
251 }
252}
253
254impl From<i128> for ScVal {
255 fn from(v: i128) -> Self {
256 ScVal::I128(Int128Parts {
257 hi: i128_hi(v),
258 lo: i128_lo(v),
259 })
260 }
261}
262
263impl From<&i128> for ScVal {
264 fn from(v: &i128) -> Self {
265 <ScVal as From<i128>>::from(*v)
266 }
267}
268
269impl From<&Int128Parts> for i128 {
270 fn from(v: &Int128Parts) -> Self {
271 i128_from_pieces(v.hi, v.lo)
272 }
273}
274
275impl TryFrom<ScVal> for i128 {
276 type Error = ();
277 fn try_from(v: ScVal) -> Result<Self, Self::Error> {
278 if let ScVal::I128(i) = v {
279 Ok((&i).into())
280 } else {
281 Err(())
282 }
283 }
284}
285
286impl From<ScSymbol> for ScVal {
287 fn from(v: ScSymbol) -> Self {
288 ScVal::Symbol(v)
289 }
290}
291
292impl TryFrom<ScVal> for ScSymbol {
293 type Error = ();
294 fn try_from(v: ScVal) -> Result<Self, Self::Error> {
295 if let ScVal::Symbol(s) = v {
296 Ok(s)
297 } else {
298 Err(())
299 }
300 }
301}
302
303#[cfg(feature = "alloc")]
304impl TryFrom<String> for ScVal {
305 type Error = ();
306 fn try_from(v: String) -> Result<Self, ()> {
307 Ok(ScVal::Symbol(v.try_into()?))
308 }
309}
310
311#[cfg(feature = "alloc")]
312impl TryFrom<&String> for ScVal {
313 type Error = ();
314 fn try_from(v: &String) -> Result<Self, ()> {
315 Ok(ScVal::Symbol(v.try_into()?))
316 }
317}
318
319#[cfg(feature = "alloc")]
320impl TryFrom<String> for ScSymbol {
321 type Error = ();
322 fn try_from(v: String) -> Result<Self, Self::Error> {
323 Ok(ScSymbol(v.try_into().map_err(|_| ())?))
324 }
325}
326
327#[cfg(feature = "alloc")]
328impl TryFrom<&String> for ScSymbol {
329 type Error = ();
330 fn try_from(v: &String) -> Result<Self, Self::Error> {
331 Ok(ScSymbol(v.try_into().map_err(|_| ())?))
332 }
333}
334
335#[cfg(feature = "alloc")]
336impl TryFrom<&str> for ScVal {
337 type Error = ();
338 fn try_from(v: &str) -> Result<Self, ()> {
339 Ok(ScVal::Symbol(v.try_into()?))
340 }
341}
342
343#[cfg(not(feature = "alloc"))]
344impl TryFrom<&'static str> for ScVal {
345 type Error = ();
346 fn try_from(v: &'static str) -> Result<Self, ()> {
347 Ok(ScVal::Symbol(v.try_into()?))
348 }
349}
350
351#[cfg(feature = "alloc")]
352impl TryFrom<&str> for ScSymbol {
353 type Error = ();
354 fn try_from(v: &str) -> Result<Self, Self::Error> {
355 Ok(ScSymbol(v.try_into().map_err(|_| ())?))
356 }
357}
358
359#[cfg(not(feature = "alloc"))]
360impl TryFrom<&'static str> for ScSymbol {
361 type Error = ();
362 fn try_from(v: &'static str) -> Result<Self, Self::Error> {
363 Ok(ScSymbol(v.try_into().map_err(|_| ())?))
364 }
365}
366
367#[cfg(feature = "alloc")]
368impl TryFrom<ScVal> for String {
369 type Error = ();
370 fn try_from(v: ScVal) -> Result<Self, Self::Error> {
371 if let ScVal::Symbol(s) = v {
372 Ok(s.0.into_utf8_string().map_err(|_| ())?)
375 } else {
376 Err(())
377 }
378 }
379}
380
381#[cfg(feature = "alloc")]
382impl TryFrom<Vec<u8>> for ScVal {
383 type Error = ();
384 fn try_from(v: Vec<u8>) -> Result<Self, ()> {
385 Ok(ScVal::Bytes(ScBytes(v.try_into().map_err(|_| ())?)))
386 }
387}
388
389#[cfg(feature = "alloc")]
390impl TryFrom<&Vec<u8>> for ScVal {
391 type Error = ();
392 fn try_from(v: &Vec<u8>) -> Result<Self, ()> {
393 Ok(ScVal::Bytes(ScBytes(v.try_into().map_err(|_| ())?)))
394 }
395}
396
397#[cfg(feature = "alloc")]
398impl TryFrom<&[u8]> for ScVal {
399 type Error = ();
400 fn try_from(v: &[u8]) -> Result<Self, ()> {
401 Ok(ScVal::Bytes(ScBytes(v.try_into().map_err(|_| ())?)))
402 }
403}
404
405#[cfg(feature = "alloc")]
406impl<const N: usize> TryFrom<[u8; N]> for ScVal {
407 type Error = ();
408 fn try_from(v: [u8; N]) -> Result<Self, ()> {
409 Ok(ScVal::Bytes(ScBytes(v.try_into().map_err(|_| ())?)))
410 }
411}
412
413#[cfg(feature = "alloc")]
414impl<const N: usize> TryFrom<&[u8; N]> for ScVal {
415 type Error = ();
416 fn try_from(v: &[u8; N]) -> Result<Self, ()> {
417 Ok(ScVal::Bytes(ScBytes(v.try_into().map_err(|_| ())?)))
418 }
419}
420
421#[cfg(not(feature = "alloc"))]
422impl TryFrom<&'static [u8]> for ScVal {
423 type Error = ();
424 fn try_from(v: &'static [u8]) -> Result<Self, ()> {
425 Ok(ScVal::Bytes(ScBytes(v.try_into().map_err(|_| ())?)))
426 }
427}
428
429#[cfg(feature = "alloc")]
430impl TryFrom<ScVal> for Vec<u8> {
431 type Error = ();
432 fn try_from(v: ScVal) -> Result<Self, Self::Error> {
433 if let ScVal::Bytes(ScBytes(b)) = v {
434 Ok(b.into())
435 } else {
436 Err(())
437 }
438 }
439}
440
441#[cfg(feature = "alloc")]
442impl TryFrom<&ScVal> for Vec<u8> {
443 type Error = ();
444 fn try_from(v: &ScVal) -> Result<Self, Self::Error> {
445 if let ScVal::Bytes(ScBytes(b)) = v {
446 Ok(b.into())
447 } else {
448 Err(())
449 }
450 }
451}
452
453impl From<ScVec> for ScVal {
454 fn from(v: ScVec) -> Self {
455 ScVal::Vec(Some(v))
456 }
457}
458
459#[cfg(feature = "alloc")]
460impl<T: TryInto<ScVal>> TryFrom<Vec<T>> for ScVal {
461 type Error = ();
462 fn try_from(v: Vec<T>) -> Result<Self, ()> {
463 Ok(ScVal::Vec(Some(
464 v.into_iter()
465 .map(|t| <_ as TryInto<ScVal>>::try_into(t))
466 .collect::<Result<Vec<_>, _>>() .map_err(|_| ())?
468 .try_into()
469 .map_err(|_| ())?,
470 )))
471 }
472}
473
474#[cfg(feature = "alloc")]
475impl<T: TryInto<ScVal> + Clone> TryFrom<&Vec<T>> for ScVal {
476 type Error = ();
477 fn try_from(v: &Vec<T>) -> Result<Self, ()> {
478 Ok(ScVal::Vec(Some(
479 v.iter()
480 .map(|t| <_ as TryInto<ScVal>>::try_into(t.clone()))
481 .collect::<Result<Vec<_>, _>>() .map_err(|_| ())?
483 .try_into()
484 .map_err(|_| ())?,
485 )))
486 }
487}
488
489#[cfg(feature = "alloc")]
490impl<T: TryInto<ScVal> + Clone> TryFrom<&[T]> for ScVal {
491 type Error = ();
492 fn try_from(v: &[T]) -> Result<Self, ()> {
493 Ok(ScVal::Vec(Some(
494 v.iter()
495 .map(|t| <_ as TryInto<ScVal>>::try_into(t.clone()))
496 .collect::<Result<Vec<_>, _>>() .map_err(|_| ())?
498 .try_into()
499 .map_err(|_| ())?,
500 )))
501 }
502}
503
504#[cfg(feature = "alloc")]
505impl<T: TryFrom<ScVal> + Clone> TryFrom<ScVal> for Vec<T> {
506 type Error = ();
507 fn try_from(v: ScVal) -> Result<Self, Self::Error> {
508 if let ScVal::Vec(Some(v)) = v {
509 v.iter()
510 .map(|t| T::try_from(t.clone()).map_err(|_| ()))
511 .collect::<Result<Vec<T>, _>>()
512 } else {
513 Err(())
514 }
515 }
516}
517
518impl From<ScMap> for ScVal {
519 fn from(v: ScMap) -> Self {
520 ScVal::Map(Some(v))
521 }
522}
523
524impl TryFrom<ScVal> for ScMap {
525 type Error = ();
526 fn try_from(v: ScVal) -> Result<Self, Self::Error> {
527 if let ScVal::Map(Some(m)) = v {
528 Ok(m)
529 } else {
530 Err(())
531 }
532 }
533}
534
535impl<K, V> TryFrom<(K, V)> for ScMapEntry
536where
537 K: TryInto<ScVal>,
538 V: TryInto<ScVal>,
539{
540 type Error = ();
541
542 fn try_from(v: (K, V)) -> Result<Self, Self::Error> {
543 Ok(ScMapEntry {
544 key: v.0.try_into().map_err(|_| ())?,
545 val: v.1.try_into().map_err(|_| ())?,
546 })
547 }
548}
549
550impl<T: Into<ScVal>> From<Option<T>> for ScVal {
554 fn from(v: Option<T>) -> Self {
555 match v {
556 Some(v) => v.into(),
557 None => ().into(),
558 }
559 }
560}
561
562impl<T> From<&Option<T>> for ScVal
563where
564 T: Into<ScVal> + Clone,
565{
566 fn from(v: &Option<T>) -> Self {
567 match v {
568 Some(v) => v.clone().into(),
569 None => ().into(),
570 }
571 }
572}
573
574macro_rules! impl_for_tuple {
575 ( $count:literal $($typ:ident $idx:tt)+ ) => {
576 #[cfg(feature = "alloc")]
577 impl<$($typ),*> TryFrom<($($typ,)*)> for ScVec
578 where
579 $($typ: TryInto<ScVal>),*
580 {
581 type Error = ();
582 fn try_from(v: ($($typ,)*)) -> Result<Self, Self::Error> {
583 let vec: Vec<ScVal> = vec![$(v.$idx.try_into().map_err(|_| ())?),+];
584 Ok(ScVec(vec.try_into()?))
585 }
586 }
587
588 #[cfg(feature = "alloc")]
589 impl<$($typ),*> TryFrom<&($($typ,)*)> for ScVec
590 where
591 $($typ: TryInto<ScVal> + Clone),*
592 {
593 type Error = ();
594 fn try_from(v: &($($typ,)*)) -> Result<Self, Self::Error> {
595 let vec: Vec<ScVal> = vec![$(v.$idx.clone().try_into().map_err(|_| ())?),+];
596 Ok(ScVec(vec.try_into()?))
597 }
598 }
599
600 #[cfg(feature = "alloc")]
601 impl<$($typ),*> TryFrom<($($typ,)*)> for ScVal
602 where
603 $($typ: TryInto<ScVal>),*
604 {
605 type Error = ();
606 fn try_from(v: ($($typ,)*)) -> Result<Self, ()> {
607 Ok(ScVal::Vec(Some(<_ as TryInto<ScVec>>::try_into(v)?)))
608 }
609 }
610
611 #[cfg(feature = "alloc")]
612 impl<$($typ),*> TryFrom<&($($typ,)*)> for ScVal
613 where
614 $($typ: TryInto<ScVal> + Clone),*
615 {
616 type Error = ();
617 fn try_from(v: &($($typ,)*)) -> Result<Self, ()> {
618 Ok(ScVal::Vec(Some(<_ as TryInto<ScVec>>::try_into(v)?)))
619 }
620 }
621
622 impl<$($typ),*> TryFrom<ScVec> for ($($typ,)*)
623 where
624 $($typ: TryFrom<ScVal> + Clone),*
627 {
628 type Error = ();
629
630 fn try_from(vec: ScVec) -> Result<Self, Self::Error> {
631 if vec.len() != $count {
632 return Err(());
633 }
634 Ok((
635 $({
636 let idx: usize = $idx;
637 let val = vec[idx].clone();
638 $typ::try_from(val).map_err(|_| ())?
639 },)*
640 ))
641 }
642 }
643
644 impl<$($typ),*> TryFrom<ScVal> for ($($typ,)*)
645 where
646 $($typ: TryFrom<ScVal> + Clone),*
647 {
648 type Error = ();
649
650 fn try_from(obj: ScVal) -> Result<Self, Self::Error> {
651 if let ScVal::Vec(Some(vec)) = obj {
652 <_ as TryFrom<ScVec>>::try_from(vec)
653 } else {
654 Err(())
655 }
656 }
657 }
658 };
659}
660
661impl_for_tuple! { 1 T0 0 }
662impl_for_tuple! { 2 T0 0 T1 1 }
663impl_for_tuple! { 3 T0 0 T1 1 T2 2 }
664impl_for_tuple! { 4 T0 0 T1 1 T2 2 T3 3 }
665impl_for_tuple! { 5 T0 0 T1 1 T2 2 T3 3 T4 4 }
666impl_for_tuple! { 6 T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 }
667impl_for_tuple! { 7 T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 }
668impl_for_tuple! { 8 T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 }
669impl_for_tuple! { 9 T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 }
670impl_for_tuple! { 10 T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 }
671impl_for_tuple! { 11 T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 }
672impl_for_tuple! { 12 T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 T11 11 }
673impl_for_tuple! { 13 T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 T11 11 T12 12 }
674
675#[cfg(test)]
676mod test {
677 use super::{int128_helpers, Int128Parts, ScVal, ScVec, UInt128Parts};
678
679 #[test]
680 fn i32_pos() {
681 let v = 5;
682 let val: ScVal = v.into();
683 assert_eq!(val, ScVal::I32(5));
684 let roundtrip: i32 = val.try_into().unwrap();
685 assert_eq!(v, roundtrip);
686 }
687
688 #[test]
689 fn i32_neg() {
690 let v = -5;
691 let val: ScVal = v.into();
692 assert_eq!(val, ScVal::I32(-5));
693 let roundtrip: i32 = val.try_into().unwrap();
694 assert_eq!(v, roundtrip);
695 }
696
697 #[test]
698 fn u32() {
699 use super::ScVal;
700
701 let v = 5u32;
702 let val: ScVal = v.into();
703 assert_eq!(val, ScVal::U32(5));
704 let roundtrip: u32 = val.try_into().unwrap();
705 assert_eq!(v, roundtrip);
706 }
707
708 #[test]
709 fn i64_pos() {
710 let v = 5i64;
711 let val: ScVal = v.into();
712 assert_eq!(val, ScVal::I64(5));
713 let roundtrip: i64 = val.try_into().unwrap();
714 assert_eq!(v, roundtrip);
715 }
716
717 #[test]
718 fn i64_neg() {
719 let v = -5i64;
720 let val: ScVal = v.into();
721 assert_eq!(val, ScVal::I64(-5));
722 let roundtrip: i64 = val.try_into().unwrap();
723 assert_eq!(v, roundtrip);
724 }
725
726 #[test]
727 fn u64() {
728 let v = 5u64;
729 let val: ScVal = v.into();
730 assert_eq!(val, ScVal::U64(5));
731 let roundtrip: u64 = val.try_into().unwrap();
732 assert_eq!(v, roundtrip);
733 }
734
735 #[test]
736 fn u128() {
737 let hi = 0x1234_5678_9abc_def0u64;
738 let lo = 0xfedc_ba98_7654_3210u64;
739 let u = int128_helpers::u128_from_pieces(hi, lo);
740 assert_eq!(u, 0x1234_5678_9abc_def0_fedc_ba98_7654_3210);
741 assert_eq!(int128_helpers::u128_hi(u), hi);
742 assert_eq!(int128_helpers::u128_lo(u), lo);
743
744 let val: ScVal = u.into();
745 assert_eq!(val, ScVal::U128(UInt128Parts { hi, lo }));
746 let roundtrip: u128 = val.try_into().unwrap();
747 assert_eq!(u, roundtrip);
748 }
749
750 #[test]
751 #[allow(clippy::cast_sign_loss, clippy::cast_possible_wrap)]
752 fn i128() {
753 let part1 = 0x00ab_cdef_9876_5432u64; let part2 = 0xfedc_ba98_7654_3210u64; let roundtrip = |hi: i64, lo: u64, ref_i128: i128| {
756 let i = int128_helpers::i128_from_pieces(hi, lo);
757 assert_eq!(i, ref_i128);
758 assert_eq!(int128_helpers::i128_hi(i), hi);
759 assert_eq!(int128_helpers::i128_lo(i), lo);
760
761 let val: ScVal = i.into();
762 assert_eq!(val, ScVal::I128(Int128Parts { hi, lo }));
763 let roundtrip: i128 = val.try_into().unwrap();
764 assert_eq!(i, roundtrip);
765 };
766 roundtrip(
767 part1 as i64,
768 part1,
769 0x00ab_cdef_9876_5432_00ab_cdef_9876_5432,
770 );
771 roundtrip(
772 part2 as i64,
773 part2,
774 0xfedc_ba98_7654_3210_fedc_ba98_7654_3210u128 as i128,
775 );
776 roundtrip(
777 part1 as i64,
778 part2,
779 0x00ab_cdef_9876_5432_fedc_ba98_7654_3210,
780 );
781 roundtrip(
782 part2 as i64,
783 part1,
784 0xfedc_ba98_7654_3210_00ab_cdef_9876_5432u128 as i128,
785 );
786 }
787
788 #[cfg(feature = "alloc")]
789 #[test]
790 fn binary() {
791 extern crate alloc;
792 use alloc::vec;
793
794 let v = [1, 2, 3, 4, 5];
795 let val: ScVal = v.try_into().unwrap();
796 assert_eq!(val, ScVal::Bytes(vec![1, 2, 3, 4, 5].try_into().unwrap()));
797
798 let v = &[1, 2, 3, 4, 5];
799 let val: ScVal = v.try_into().unwrap();
800 assert_eq!(val, ScVal::Bytes(vec![1, 2, 3, 4, 5].try_into().unwrap()));
801 }
802
803 #[cfg(feature = "alloc")]
804 #[test]
805 fn vec() {
806 extern crate alloc;
807 use alloc::vec;
808 use alloc::vec::Vec;
809
810 let v = vec![1, 2, 3, 4, 5];
811 let val: ScVal = v.clone().try_into().unwrap();
812 let roundtrip: Vec<i32> = val.try_into().unwrap();
813 assert_eq!(v, roundtrip);
814
815 let v = vec![vec![true], vec![false]];
816 let val: ScVal = v.clone().try_into().unwrap();
817 let roundtrip: Vec<Vec<bool>> = val.try_into().unwrap();
818 assert_eq!(v, roundtrip);
819 }
820
821 #[cfg(feature = "alloc")]
822 #[test]
823 fn tuple() {
824 extern crate alloc;
825 use alloc::vec;
826 use alloc::vec::Vec;
827 let v = (1i32, 2i64, vec![true, false]);
828 let val: ScVal = v.clone().try_into().unwrap();
829 let roundtrip: (i32, i64, Vec<bool>) = val.try_into().unwrap();
830 assert_eq!(v, roundtrip);
831 }
832
833 #[cfg(feature = "alloc")]
834 #[test]
835 fn tuple_refs() {
836 extern crate alloc;
837 use alloc::vec;
838 use alloc::vec::Vec;
839 let v = &(1i32, 2i64, vec![true, false]);
840 let val: ScVal = v.try_into().unwrap();
841 let roundtrip: (i32, i64, Vec<bool>) = val.try_into().unwrap();
842 assert_eq!(v, &roundtrip);
843 }
844
845 #[test]
846 fn option() {
847 let v: Option<i64> = Some(1);
848 let val: ScVal = v.into();
849 assert_eq!(val, ScVal::I64(1));
850
851 let v: Option<i64> = None;
852 let val: ScVal = v.into();
853 assert_eq!(val, ScVal::Void);
854 }
855
856 #[test]
857 fn scval_from() {
858 let _ = ScVal::from(ScVec::default());
859 }
860}