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 ScSymbol {
305 type Error = ();
306 fn try_from(v: String) -> Result<Self, Self::Error> {
307 Ok(ScSymbol(v.try_into().map_err(|_| ())?))
308 }
309}
310
311#[cfg(feature = "alloc")]
312impl TryFrom<&String> for ScSymbol {
313 type Error = ();
314 fn try_from(v: &String) -> Result<Self, Self::Error> {
315 Ok(ScSymbol(v.try_into().map_err(|_| ())?))
316 }
317}
318
319#[cfg(feature = "alloc")]
320impl TryFrom<&str> for ScSymbol {
321 type Error = ();
322 fn try_from(v: &str) -> Result<Self, Self::Error> {
323 Ok(ScSymbol(v.try_into().map_err(|_| ())?))
324 }
325}
326
327#[cfg(not(feature = "alloc"))]
328impl TryFrom<&'static str> for ScSymbol {
329 type Error = ();
330 fn try_from(v: &'static str) -> Result<Self, Self::Error> {
331 Ok(ScSymbol(v.try_into().map_err(|_| ())?))
332 }
333}
334
335#[cfg(feature = "alloc")]
336impl TryFrom<Vec<u8>> for ScVal {
337 type Error = ();
338 fn try_from(v: Vec<u8>) -> Result<Self, ()> {
339 Ok(ScVal::Bytes(ScBytes(v.try_into().map_err(|_| ())?)))
340 }
341}
342
343#[cfg(feature = "alloc")]
344impl TryFrom<&Vec<u8>> for ScVal {
345 type Error = ();
346 fn try_from(v: &Vec<u8>) -> Result<Self, ()> {
347 Ok(ScVal::Bytes(ScBytes(v.try_into().map_err(|_| ())?)))
348 }
349}
350
351#[cfg(feature = "alloc")]
352impl TryFrom<&[u8]> for ScVal {
353 type Error = ();
354 fn try_from(v: &[u8]) -> Result<Self, ()> {
355 Ok(ScVal::Bytes(ScBytes(v.try_into().map_err(|_| ())?)))
356 }
357}
358
359#[cfg(feature = "alloc")]
360impl<const N: usize> TryFrom<[u8; N]> for ScVal {
361 type Error = ();
362 fn try_from(v: [u8; N]) -> Result<Self, ()> {
363 Ok(ScVal::Bytes(ScBytes(v.try_into().map_err(|_| ())?)))
364 }
365}
366
367#[cfg(feature = "alloc")]
368impl<const N: usize> TryFrom<&[u8; N]> for ScVal {
369 type Error = ();
370 fn try_from(v: &[u8; N]) -> Result<Self, ()> {
371 Ok(ScVal::Bytes(ScBytes(v.try_into().map_err(|_| ())?)))
372 }
373}
374
375#[cfg(not(feature = "alloc"))]
376impl TryFrom<&'static [u8]> for ScVal {
377 type Error = ();
378 fn try_from(v: &'static [u8]) -> Result<Self, ()> {
379 Ok(ScVal::Bytes(ScBytes(v.try_into().map_err(|_| ())?)))
380 }
381}
382
383#[cfg(feature = "alloc")]
384impl TryFrom<ScVal> for Vec<u8> {
385 type Error = ();
386 fn try_from(v: ScVal) -> Result<Self, Self::Error> {
387 if let ScVal::Bytes(ScBytes(b)) = v {
388 Ok(b.into())
389 } else {
390 Err(())
391 }
392 }
393}
394
395#[cfg(feature = "alloc")]
396impl TryFrom<&ScVal> for Vec<u8> {
397 type Error = ();
398 fn try_from(v: &ScVal) -> Result<Self, Self::Error> {
399 if let ScVal::Bytes(ScBytes(b)) = v {
400 Ok(b.into())
401 } else {
402 Err(())
403 }
404 }
405}
406
407impl From<ScVec> for ScVal {
408 fn from(v: ScVec) -> Self {
409 ScVal::Vec(Some(v))
410 }
411}
412
413#[cfg(feature = "alloc")]
414impl<T: TryInto<ScVal>> TryFrom<Vec<T>> for ScVal {
415 type Error = ();
416 fn try_from(v: Vec<T>) -> Result<Self, ()> {
417 Ok(ScVal::Vec(Some(
418 v.into_iter()
419 .map(|t| <_ as TryInto<ScVal>>::try_into(t))
420 .collect::<Result<Vec<_>, _>>() .map_err(|_| ())?
422 .try_into()
423 .map_err(|_| ())?,
424 )))
425 }
426}
427
428#[cfg(feature = "alloc")]
429impl<T: TryInto<ScVal> + Clone> TryFrom<&Vec<T>> for ScVal {
430 type Error = ();
431 fn try_from(v: &Vec<T>) -> Result<Self, ()> {
432 Ok(ScVal::Vec(Some(
433 v.iter()
434 .map(|t| <_ as TryInto<ScVal>>::try_into(t.clone()))
435 .collect::<Result<Vec<_>, _>>() .map_err(|_| ())?
437 .try_into()
438 .map_err(|_| ())?,
439 )))
440 }
441}
442
443#[cfg(feature = "alloc")]
444impl<T: TryInto<ScVal> + Clone> TryFrom<&[T]> for ScVal {
445 type Error = ();
446 fn try_from(v: &[T]) -> Result<Self, ()> {
447 Ok(ScVal::Vec(Some(
448 v.iter()
449 .map(|t| <_ as TryInto<ScVal>>::try_into(t.clone()))
450 .collect::<Result<Vec<_>, _>>() .map_err(|_| ())?
452 .try_into()
453 .map_err(|_| ())?,
454 )))
455 }
456}
457
458#[cfg(feature = "alloc")]
459impl<T: TryFrom<ScVal> + Clone> TryFrom<ScVal> for Vec<T> {
460 type Error = ();
461 fn try_from(v: ScVal) -> Result<Self, Self::Error> {
462 if let ScVal::Vec(Some(v)) = v {
463 v.iter()
464 .map(|t| T::try_from(t.clone()).map_err(|_| ()))
465 .collect::<Result<Vec<T>, _>>()
466 } else {
467 Err(())
468 }
469 }
470}
471
472impl From<ScMap> for ScVal {
473 fn from(v: ScMap) -> Self {
474 ScVal::Map(Some(v))
475 }
476}
477
478impl TryFrom<ScVal> for ScMap {
479 type Error = ();
480 fn try_from(v: ScVal) -> Result<Self, Self::Error> {
481 if let ScVal::Map(Some(m)) = v {
482 Ok(m)
483 } else {
484 Err(())
485 }
486 }
487}
488
489impl<K, V> TryFrom<(K, V)> for ScMapEntry
490where
491 K: TryInto<ScVal>,
492 V: TryInto<ScVal>,
493{
494 type Error = ();
495
496 fn try_from(v: (K, V)) -> Result<Self, Self::Error> {
497 Ok(ScMapEntry {
498 key: v.0.try_into().map_err(|_| ())?,
499 val: v.1.try_into().map_err(|_| ())?,
500 })
501 }
502}
503
504impl<T> From<Option<T>> for ScVal
508where
509 T: Into<ScVal>,
510{
511 fn from(v: Option<T>) -> Self {
512 match v {
513 Some(v) => v.into(),
514 None => ().into(),
515 }
516 }
517}
518
519impl<T> From<&Option<T>> for ScVal
520where
521 T: Into<ScVal> + Clone,
522{
523 fn from(v: &Option<T>) -> Self {
524 match v {
525 Some(v) => v.clone().into(),
526 None => ().into(),
527 }
528 }
529}
530
531macro_rules! impl_for_tuple {
532 ( $count:literal $($typ:ident $idx:tt)+ ) => {
533 #[cfg(feature = "alloc")]
534 impl<$($typ),*> TryFrom<($($typ,)*)> for ScVec
535 where
536 $($typ: TryInto<ScVal>),*
537 {
538 type Error = ();
539 fn try_from(v: ($($typ,)*)) -> Result<Self, Self::Error> {
540 let vec: Vec<ScVal> = vec![$(v.$idx.try_into().map_err(|_| ())?),+];
541 Ok(ScVec(vec.try_into()?))
542 }
543 }
544
545 #[cfg(feature = "alloc")]
546 impl<$($typ),*> TryFrom<&($($typ,)*)> for ScVec
547 where
548 $($typ: TryInto<ScVal> + Clone),*
549 {
550 type Error = ();
551 fn try_from(v: &($($typ,)*)) -> Result<Self, Self::Error> {
552 let vec: Vec<ScVal> = vec![$(v.$idx.clone().try_into().map_err(|_| ())?),+];
553 Ok(ScVec(vec.try_into()?))
554 }
555 }
556
557 #[cfg(feature = "alloc")]
558 impl<$($typ),*> TryFrom<($($typ,)*)> for ScVal
559 where
560 $($typ: TryInto<ScVal>),*
561 {
562 type Error = ();
563 fn try_from(v: ($($typ,)*)) -> Result<Self, ()> {
564 Ok(ScVal::Vec(Some(<_ as TryInto<ScVec>>::try_into(v)?)))
565 }
566 }
567
568 #[cfg(feature = "alloc")]
569 impl<$($typ),*> TryFrom<&($($typ,)*)> for ScVal
570 where
571 $($typ: TryInto<ScVal> + Clone),*
572 {
573 type Error = ();
574 fn try_from(v: &($($typ,)*)) -> Result<Self, ()> {
575 Ok(ScVal::Vec(Some(<_ as TryInto<ScVec>>::try_into(v)?)))
576 }
577 }
578
579 impl<$($typ),*> TryFrom<ScVec> for ($($typ,)*)
580 where
581 $($typ: TryFrom<ScVal> + Clone),*
584 {
585 type Error = ();
586
587 fn try_from(vec: ScVec) -> Result<Self, Self::Error> {
588 if vec.len() != $count {
589 return Err(());
590 }
591 Ok((
592 $({
593 let idx: usize = $idx;
594 let val = vec[idx].clone();
595 $typ::try_from(val).map_err(|_| ())?
596 },)*
597 ))
598 }
599 }
600
601 impl<$($typ),*> TryFrom<ScVal> for ($($typ,)*)
602 where
603 $($typ: TryFrom<ScVal> + Clone),*
604 {
605 type Error = ();
606
607 fn try_from(obj: ScVal) -> Result<Self, Self::Error> {
608 if let ScVal::Vec(Some(vec)) = obj {
609 <_ as TryFrom<ScVec>>::try_from(vec)
610 } else {
611 Err(())
612 }
613 }
614 }
615 };
616}
617
618impl_for_tuple! { 1 T0 0 }
619impl_for_tuple! { 2 T0 0 T1 1 }
620impl_for_tuple! { 3 T0 0 T1 1 T2 2 }
621impl_for_tuple! { 4 T0 0 T1 1 T2 2 T3 3 }
622impl_for_tuple! { 5 T0 0 T1 1 T2 2 T3 3 T4 4 }
623impl_for_tuple! { 6 T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 }
624impl_for_tuple! { 7 T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 }
625impl_for_tuple! { 8 T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 }
626impl_for_tuple! { 9 T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 }
627impl_for_tuple! { 10 T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 }
628impl_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 }
629impl_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 }
630impl_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 }
631
632#[cfg(test)]
633mod test {
634 use super::{int128_helpers, Int128Parts, ScVal, ScVec, UInt128Parts};
635
636 #[test]
637 fn i32_pos() {
638 let v = 5;
639 let val: ScVal = v.into();
640 assert_eq!(val, ScVal::I32(5));
641 let roundtrip: i32 = val.try_into().unwrap();
642 assert_eq!(v, roundtrip);
643 }
644
645 #[test]
646 fn i32_neg() {
647 let v = -5;
648 let val: ScVal = v.into();
649 assert_eq!(val, ScVal::I32(-5));
650 let roundtrip: i32 = val.try_into().unwrap();
651 assert_eq!(v, roundtrip);
652 }
653
654 #[test]
655 fn u32() {
656 use super::ScVal;
657
658 let v = 5u32;
659 let val: ScVal = v.into();
660 assert_eq!(val, ScVal::U32(5));
661 let roundtrip: u32 = val.try_into().unwrap();
662 assert_eq!(v, roundtrip);
663 }
664
665 #[test]
666 fn i64_pos() {
667 let v = 5i64;
668 let val: ScVal = v.into();
669 assert_eq!(val, ScVal::I64(5));
670 let roundtrip: i64 = val.try_into().unwrap();
671 assert_eq!(v, roundtrip);
672 }
673
674 #[test]
675 fn i64_neg() {
676 let v = -5i64;
677 let val: ScVal = v.into();
678 assert_eq!(val, ScVal::I64(-5));
679 let roundtrip: i64 = val.try_into().unwrap();
680 assert_eq!(v, roundtrip);
681 }
682
683 #[test]
684 fn u64() {
685 let v = 5u64;
686 let val: ScVal = v.into();
687 assert_eq!(val, ScVal::U64(5));
688 let roundtrip: u64 = val.try_into().unwrap();
689 assert_eq!(v, roundtrip);
690 }
691
692 #[test]
693 fn u128() {
694 let hi = 0x1234_5678_9abc_def0u64;
695 let lo = 0xfedc_ba98_7654_3210u64;
696 let u = int128_helpers::u128_from_pieces(hi, lo);
697 assert_eq!(u, 0x1234_5678_9abc_def0_fedc_ba98_7654_3210);
698 assert_eq!(int128_helpers::u128_hi(u), hi);
699 assert_eq!(int128_helpers::u128_lo(u), lo);
700
701 let val: ScVal = u.into();
702 assert_eq!(val, ScVal::U128(UInt128Parts { hi, lo }));
703 let roundtrip: u128 = val.try_into().unwrap();
704 assert_eq!(u, roundtrip);
705 }
706
707 #[test]
708 #[allow(clippy::cast_sign_loss, clippy::cast_possible_wrap)]
709 fn i128() {
710 let part1 = 0x00ab_cdef_9876_5432u64; let part2 = 0xfedc_ba98_7654_3210u64; let roundtrip = |hi: i64, lo: u64, ref_i128: i128| {
713 let i = int128_helpers::i128_from_pieces(hi, lo);
714 assert_eq!(i, ref_i128);
715 assert_eq!(int128_helpers::i128_hi(i), hi);
716 assert_eq!(int128_helpers::i128_lo(i), lo);
717
718 let val: ScVal = i.into();
719 assert_eq!(val, ScVal::I128(Int128Parts { hi, lo }));
720 let roundtrip: i128 = val.try_into().unwrap();
721 assert_eq!(i, roundtrip);
722 };
723 roundtrip(
724 part1 as i64,
725 part1,
726 0x00ab_cdef_9876_5432_00ab_cdef_9876_5432,
727 );
728 roundtrip(
729 part2 as i64,
730 part2,
731 0xfedc_ba98_7654_3210_fedc_ba98_7654_3210u128 as i128,
732 );
733 roundtrip(
734 part1 as i64,
735 part2,
736 0x00ab_cdef_9876_5432_fedc_ba98_7654_3210,
737 );
738 roundtrip(
739 part2 as i64,
740 part1,
741 0xfedc_ba98_7654_3210_00ab_cdef_9876_5432u128 as i128,
742 );
743 }
744
745 #[cfg(feature = "alloc")]
746 #[test]
747 fn binary() {
748 extern crate alloc;
749 use alloc::vec;
750
751 let v = [1, 2, 3, 4, 5];
752 let val: ScVal = v.try_into().unwrap();
753 assert_eq!(val, ScVal::Bytes(vec![1, 2, 3, 4, 5].try_into().unwrap()));
754
755 let v = &[1, 2, 3, 4, 5];
756 let val: ScVal = v.try_into().unwrap();
757 assert_eq!(val, ScVal::Bytes(vec![1, 2, 3, 4, 5].try_into().unwrap()));
758 }
759
760 #[cfg(feature = "alloc")]
761 #[test]
762 fn vec() {
763 extern crate alloc;
764 use alloc::vec;
765 use alloc::vec::Vec;
766
767 let v = vec![1, 2, 3, 4, 5];
768 let val: ScVal = v.clone().try_into().unwrap();
769 let roundtrip: Vec<i32> = val.try_into().unwrap();
770 assert_eq!(v, roundtrip);
771
772 let v = vec![vec![true], vec![false]];
773 let val: ScVal = v.clone().try_into().unwrap();
774 let roundtrip: Vec<Vec<bool>> = val.try_into().unwrap();
775 assert_eq!(v, roundtrip);
776 }
777
778 #[cfg(feature = "alloc")]
779 #[test]
780 fn tuple() {
781 extern crate alloc;
782 use alloc::vec;
783 use alloc::vec::Vec;
784 let v = (1i32, 2i64, vec![true, false]);
785 let val: ScVal = v.clone().try_into().unwrap();
786 let roundtrip: (i32, i64, Vec<bool>) = val.try_into().unwrap();
787 assert_eq!(v, roundtrip);
788 }
789
790 #[cfg(feature = "alloc")]
791 #[test]
792 fn tuple_refs() {
793 extern crate alloc;
794 use alloc::vec;
795 use alloc::vec::Vec;
796 let v = &(1i32, 2i64, vec![true, false]);
797 let val: ScVal = v.try_into().unwrap();
798 let roundtrip: (i32, i64, Vec<bool>) = val.try_into().unwrap();
799 assert_eq!(v, &roundtrip);
800 }
801
802 #[test]
803 fn option() {
804 let v: Option<i64> = Some(1);
805 let val: ScVal = v.into();
806 assert_eq!(val, ScVal::I64(1));
807
808 let v: Option<i64> = None;
809 let val: ScVal = v.into();
810 assert_eq!(val, ScVal::Void);
811 }
812
813 #[test]
814 fn scval_from() {
815 let _ = ScVal::from(ScVec::default());
816 }
817}