1use std::sync::Arc;
25
26#[crate::polydat_node(category = Conversions)]
31fn __u8_to_u64(n: u8) -> u64 {
32 n as u64
33}
34
35#[crate::polydat_node(category = Conversions)]
36fn __u8_to_u32(n: u8) -> u32 {
37 n as u32
38}
39
40#[crate::polydat_node(category = Conversions)]
41fn __u8_to_u16(n: u8) -> u16 {
42 n as u16
43}
44
45#[crate::polydat_node(category = Conversions)]
46fn __u8_to_f64(n: u8) -> f64 {
47 n as f64
48}
49
50#[crate::polydat_node(category = Conversions)]
51fn __u16_to_u64(n: u16) -> u64 {
52 n as u64
53}
54
55#[crate::polydat_node(category = Conversions)]
56fn __u16_to_u32(n: u16) -> u32 {
57 n as u32
58}
59
60#[crate::polydat_node(category = Conversions)]
61fn __u16_to_f64(n: u16) -> f64 {
62 n as f64
63}
64
65#[crate::polydat_node(category = Conversions)]
66fn __i8_to_i64(n: i8) -> i64 {
67 n as i64
68}
69
70#[crate::polydat_node(category = Conversions)]
71fn __i8_to_i32(n: i8) -> i32 {
72 n as i32
73}
74
75#[crate::polydat_node(category = Conversions)]
76fn __i8_to_i16(n: i8) -> i16 {
77 n as i16
78}
79
80#[crate::polydat_node(category = Conversions)]
81fn __i8_to_f64(n: i8) -> f64 {
82 n as f64
83}
84
85#[crate::polydat_node(category = Conversions)]
86fn __i16_to_i64(n: i16) -> i64 {
87 n as i64
88}
89
90#[crate::polydat_node(category = Conversions)]
91fn __i16_to_i32(n: i16) -> i32 {
92 n as i32
93}
94
95#[crate::polydat_node(category = Conversions)]
96fn __i16_to_f64(n: i16) -> f64 {
97 n as f64
98}
99
100#[crate::polydat_node(category = Conversions)]
102fn __f16_to_f32(f: half::f16) -> f32 {
103 f.to_f32()
104}
105
106#[crate::polydat_node(category = Conversions)]
107fn __f16_to_f64(f: half::f16) -> f64 {
108 f.to_f64()
109}
110
111#[crate::polydat_node(category = Conversions)]
117fn __u8_to_i16(n: u8) -> i16 {
118 n as i16
119}
120
121#[crate::polydat_node(category = Conversions)]
122fn __u8_to_i32(n: u8) -> i32 {
123 n as i32
124}
125
126#[crate::polydat_node(category = Conversions)]
127fn __u8_to_i64(n: u8) -> i64 {
128 n as i64
129}
130
131#[crate::polydat_node(category = Conversions)]
132fn __u8_to_f32(n: u8) -> f32 {
133 n as f32
134}
135
136#[crate::polydat_node(category = Conversions)]
137fn __u16_to_i32(n: u16) -> i32 {
138 n as i32
139}
140
141#[crate::polydat_node(category = Conversions)]
142fn __u16_to_i64(n: u16) -> i64 {
143 n as i64
144}
145
146#[crate::polydat_node(category = Conversions)]
147fn __u16_to_f32(n: u16) -> f32 {
148 n as f32
149}
150
151#[crate::polydat_node(category = Conversions)]
152fn __i8_to_f32(n: i8) -> f32 {
153 n as f32
154}
155
156#[crate::polydat_node(category = Conversions)]
157fn __i16_to_f32(n: i16) -> f32 {
158 n as f32
159}
160
161#[crate::polydat_node(category = Conversions)]
164fn __u8_to_f16(n: u8) -> half::f16 {
165 half::f16::from_f32(n as f32)
166}
167
168#[crate::polydat_node(category = Conversions)]
169fn __i8_to_f16(n: i8) -> half::f16 {
170 half::f16::from_f32(n as f32)
171}
172
173#[crate::polydat_node(category = Conversions)]
178fn __u64_to_u8(n: u64) -> u8 {
179 if n > u8::MAX as u64 {
180 panic!("__u64_to_u8: value {n} exceeds u8::MAX ({})", u8::MAX);
181 }
182 n as u8
183}
184
185#[crate::polydat_node(category = Conversions)]
186fn __u32_to_u8(n: u32) -> u8 {
187 if n > u8::MAX as u32 {
188 panic!("__u32_to_u8: value {n} exceeds u8::MAX ({})", u8::MAX);
189 }
190 n as u8
191}
192
193#[crate::polydat_node(category = Conversions)]
194fn __u16_to_u8(n: u16) -> u8 {
195 if n > u8::MAX as u16 {
196 panic!("__u16_to_u8: value {n} exceeds u8::MAX ({})", u8::MAX);
197 }
198 n as u8
199}
200
201#[crate::polydat_node(category = Conversions)]
202fn __i64_to_u8(n: i64) -> u8 {
203 if n < 0 || n > u8::MAX as i64 {
204 panic!("__i64_to_u8: value {n} out of u8 range [0, {}]", u8::MAX);
205 }
206 n as u8
207}
208
209#[crate::polydat_node(category = Conversions)]
210fn __f64_to_u8(f: f64) -> u8 {
211 if !f.is_finite() {
212 panic!("__f64_to_u8: non-finite value {f} cannot be represented as u8");
213 }
214 let n = f.trunc();
215 if n < 0.0 || n > u8::MAX as f64 {
216 panic!("__f64_to_u8: value {f} out of u8 range [0, {}]", u8::MAX);
217 }
218 n as u8
219}
220
221#[crate::polydat_node(category = Conversions)]
222fn __u64_to_u16(n: u64) -> u16 {
223 if n > u16::MAX as u64 {
224 panic!("__u64_to_u16: value {n} exceeds u16::MAX ({})", u16::MAX);
225 }
226 n as u16
227}
228
229#[crate::polydat_node(category = Conversions)]
230fn __u32_to_u16(n: u32) -> u16 {
231 if n > u16::MAX as u32 {
232 panic!("__u32_to_u16: value {n} exceeds u16::MAX ({})", u16::MAX);
233 }
234 n as u16
235}
236
237#[crate::polydat_node(category = Conversions)]
238fn __i64_to_u16(n: i64) -> u16 {
239 if n < 0 || n > u16::MAX as i64 {
240 panic!("__i64_to_u16: value {n} out of u16 range [0, {}]", u16::MAX);
241 }
242 n as u16
243}
244
245#[crate::polydat_node(category = Conversions)]
246fn __f64_to_u16(f: f64) -> u16 {
247 if !f.is_finite() {
248 panic!("__f64_to_u16: non-finite value {f} cannot be represented as u16");
249 }
250 let n = f.trunc();
251 if n < 0.0 || n > u16::MAX as f64 {
252 panic!("__f64_to_u16: value {f} out of u16 range [0, {}]", u16::MAX);
253 }
254 n as u16
255}
256
257#[crate::polydat_node(category = Conversions)]
258fn __i64_to_i8(n: i64) -> i8 {
259 if n < i8::MIN as i64 || n > i8::MAX as i64 {
260 panic!(
261 "__i64_to_i8: value {n} out of i8 range [{}, {}]",
262 i8::MIN,
263 i8::MAX
264 );
265 }
266 n as i8
267}
268
269#[crate::polydat_node(category = Conversions)]
270fn __i32_to_i8(n: i32) -> i8 {
271 if n < i8::MIN as i32 || n > i8::MAX as i32 {
272 panic!(
273 "__i32_to_i8: value {n} out of i8 range [{}, {}]",
274 i8::MIN,
275 i8::MAX
276 );
277 }
278 n as i8
279}
280
281#[crate::polydat_node(category = Conversions)]
282fn __u64_to_i8(n: u64) -> i8 {
283 if n > i8::MAX as u64 {
284 panic!("__u64_to_i8: value {n} exceeds i8::MAX ({})", i8::MAX);
285 }
286 n as i8
287}
288
289#[crate::polydat_node(category = Conversions)]
290fn __f64_to_i8(f: f64) -> i8 {
291 if !f.is_finite() {
292 panic!("__f64_to_i8: non-finite value {f} cannot be represented as i8");
293 }
294 let n = f.trunc();
295 if n < i8::MIN as f64 || n > i8::MAX as f64 {
296 panic!(
297 "__f64_to_i8: value {f} out of i8 range [{}, {}]",
298 i8::MIN,
299 i8::MAX
300 );
301 }
302 n as i8
303}
304
305#[crate::polydat_node(category = Conversions)]
306fn __i64_to_i16(n: i64) -> i16 {
307 if n < i16::MIN as i64 || n > i16::MAX as i64 {
308 panic!(
309 "__i64_to_i16: value {n} out of i16 range [{}, {}]",
310 i16::MIN,
311 i16::MAX
312 );
313 }
314 n as i16
315}
316
317#[crate::polydat_node(category = Conversions)]
318fn __i32_to_i16(n: i32) -> i16 {
319 if n < i16::MIN as i32 || n > i16::MAX as i32 {
320 panic!(
321 "__i32_to_i16: value {n} out of i16 range [{}, {}]",
322 i16::MIN,
323 i16::MAX
324 );
325 }
326 n as i16
327}
328
329#[crate::polydat_node(category = Conversions)]
330fn __u64_to_i16(n: u64) -> i16 {
331 if n > i16::MAX as u64 {
332 panic!("__u64_to_i16: value {n} exceeds i16::MAX ({})", i16::MAX);
333 }
334 n as i16
335}
336
337#[crate::polydat_node(category = Conversions)]
338fn __f64_to_i16(f: f64) -> i16 {
339 if !f.is_finite() {
340 panic!("__f64_to_i16: non-finite value {f} cannot be represented as i16");
341 }
342 let n = f.trunc();
343 if n < i16::MIN as f64 || n > i16::MAX as f64 {
344 panic!(
345 "__f64_to_i16: value {f} out of i16 range [{}, {}]",
346 i16::MIN,
347 i16::MAX
348 );
349 }
350 n as i16
351}
352
353#[crate::polydat_node(category = Conversions)]
358fn __f64_to_f16(f: f64) -> half::f16 {
359 half::f16::from_f64(f)
360}
361
362#[crate::polydat_node(category = Conversions)]
363fn __f32_to_f16(f: f32) -> half::f16 {
364 half::f16::from_f32(f)
365}
366
367#[crate::polydat_node(category = Conversions)]
368fn __u64_to_f16(n: u64) -> half::f16 {
369 half::f16::from_f64(n as f64)
370}
371
372#[crate::polydat_node(category = Conversions)]
377fn __bool_to_u8(b: bool) -> u8 {
378 if b { 1 } else { 0 }
379}
380
381#[crate::polydat_node(category = Conversions)]
382fn __bool_to_u16(b: bool) -> u16 {
383 if b { 1 } else { 0 }
384}
385
386#[crate::polydat_node(category = Conversions)]
387fn __bool_to_i8(b: bool) -> i8 {
388 if b { 1 } else { 0 }
389}
390
391#[crate::polydat_node(category = Conversions)]
392fn __bool_to_i16(b: bool) -> i16 {
393 if b { 1 } else { 0 }
394}
395
396#[crate::polydat_node(category = Conversions)]
397fn __bool_to_f16(b: bool) -> half::f16 {
398 if b { half::f16::ONE } else { half::f16::ZERO }
399}
400
401#[crate::polydat_node(category = Conversions)]
402fn __u8_to_bool(n: u8) -> bool {
403 n != 0
404}
405
406#[crate::polydat_node(category = Conversions)]
407fn __u16_to_bool(n: u16) -> bool {
408 n != 0
409}
410
411#[crate::polydat_node(category = Conversions)]
412fn __i8_to_bool(n: i8) -> bool {
413 n != 0
414}
415
416#[crate::polydat_node(category = Conversions)]
417fn __i16_to_bool(n: i16) -> bool {
418 n != 0
419}
420
421#[crate::polydat_node(category = Conversions)]
422fn __f16_to_bool(f: half::f16) -> bool {
423 f != half::f16::ZERO && f != half::f16::NEG_ZERO && !f.is_nan()
424}
425
426#[crate::polydat_node(category = Conversions)]
431fn __u8_to_string(n: u8) -> String {
432 n.to_string()
433}
434
435#[crate::polydat_node(category = Conversions)]
436fn __u16_to_string(n: u16) -> String {
437 n.to_string()
438}
439
440#[crate::polydat_node(category = Conversions)]
441fn __i8_to_string(n: i8) -> String {
442 n.to_string()
443}
444
445#[crate::polydat_node(category = Conversions)]
446fn __i16_to_string(n: i16) -> String {
447 n.to_string()
448}
449
450#[crate::polydat_node(category = Conversions)]
453fn __f16_to_string(f: half::f16) -> String {
454 format!("{:?}", f.to_f32())
455}
456
457#[crate::polydat_node(category = Conversions)]
462fn __str_to_u8(input: &str) -> u8 {
463 let raw = input.trim();
464 raw.parse::<u8>()
465 .unwrap_or_else(|e| panic!("__str_to_u8: cannot parse {raw:?} as u8: {e}"))
466}
467
468#[crate::polydat_node(category = Conversions)]
469fn __str_to_u16(input: &str) -> u16 {
470 let raw = input.trim();
471 raw.parse::<u16>()
472 .unwrap_or_else(|e| panic!("__str_to_u16: cannot parse {raw:?} as u16: {e}"))
473}
474
475#[crate::polydat_node(category = Conversions)]
476fn __str_to_i8(input: &str) -> i8 {
477 let raw = input.trim();
478 raw.parse::<i8>()
479 .unwrap_or_else(|e| panic!("__str_to_i8: cannot parse {raw:?} as i8: {e}"))
480}
481
482#[crate::polydat_node(category = Conversions)]
483fn __str_to_i16(input: &str) -> i16 {
484 let raw = input.trim();
485 raw.parse::<i16>()
486 .unwrap_or_else(|e| panic!("__str_to_i16: cannot parse {raw:?} as i16: {e}"))
487}
488
489#[crate::polydat_node(category = Conversions)]
490fn __str_to_f16(input: &str) -> half::f16 {
491 let raw = input.trim();
492 let f: f32 = raw
493 .parse()
494 .unwrap_or_else(|e| panic!("__str_to_f16: cannot parse {raw:?} as f16: {e}"));
495 half::f16::from_f32(f)
496}
497
498#[crate::polydat_node(category = Conversions)]
503fn __u8_to_bytes(n: u8) -> Vec<u8> {
504 vec![n]
505}
506
507#[crate::polydat_node(category = Conversions)]
508fn __u16_to_bytes(n: u16) -> Vec<u8> {
509 n.to_le_bytes().to_vec()
510}
511
512#[crate::polydat_node(category = Conversions)]
513fn __i8_to_bytes(n: i8) -> Vec<u8> {
514 n.to_le_bytes().to_vec()
515}
516
517#[crate::polydat_node(category = Conversions)]
518fn __i16_to_bytes(n: i16) -> Vec<u8> {
519 n.to_le_bytes().to_vec()
520}
521
522#[crate::polydat_node(category = Conversions)]
523fn __f16_to_bytes(f: half::f16) -> Vec<u8> {
524 f.to_bits().to_le_bytes().to_vec()
525}
526
527#[crate::polydat_node(category = Conversions)]
528fn __bytes_to_u8(b: &[u8]) -> u8 {
529 if b.len() != 1 {
530 panic!(
531 "__bytes_to_u8: expected exactly 1 byte for u8, got {}",
532 b.len()
533 );
534 }
535 b[0]
536}
537
538#[crate::polydat_node(category = Conversions)]
539fn __bytes_to_u16(b: &[u8]) -> u16 {
540 if b.len() != 2 {
541 panic!(
542 "__bytes_to_u16: expected exactly 2 bytes for u16, got {}",
543 b.len()
544 );
545 }
546 u16::from_le_bytes(b.try_into().unwrap())
547}
548
549#[crate::polydat_node(category = Conversions)]
550fn __bytes_to_i8(b: &[u8]) -> i8 {
551 if b.len() != 1 {
552 panic!(
553 "__bytes_to_i8: expected exactly 1 byte for i8, got {}",
554 b.len()
555 );
556 }
557 b[0] as i8
558}
559
560#[crate::polydat_node(category = Conversions)]
561fn __bytes_to_i16(b: &[u8]) -> i16 {
562 if b.len() != 2 {
563 panic!(
564 "__bytes_to_i16: expected exactly 2 bytes for i16, got {}",
565 b.len()
566 );
567 }
568 i16::from_le_bytes(b.try_into().unwrap())
569}
570
571#[crate::polydat_node(category = Conversions)]
572fn __bytes_to_f16(b: &[u8]) -> half::f16 {
573 if b.len() != 2 {
574 panic!(
575 "__bytes_to_f16: expected exactly 2 bytes for f16, got {}",
576 b.len()
577 );
578 }
579 half::f16::from_bits(u16::from_le_bytes(b.try_into().unwrap()))
580}
581
582#[crate::polydat_node(category = Conversions)]
588fn __u8_to_json(n: u8) -> Arc<serde_json::Value> {
589 Arc::new(serde_json::Value::from(n as u64))
590}
591
592#[crate::polydat_node(category = Conversions)]
593fn __u16_to_json(n: u16) -> Arc<serde_json::Value> {
594 Arc::new(serde_json::Value::from(n as u64))
595}
596
597#[crate::polydat_node(category = Conversions)]
598fn __i8_to_json(n: i8) -> Arc<serde_json::Value> {
599 Arc::new(serde_json::Value::from(n as i64))
600}
601
602#[crate::polydat_node(category = Conversions)]
603fn __i16_to_json(n: i16) -> Arc<serde_json::Value> {
604 Arc::new(serde_json::Value::from(n as i64))
605}
606
607#[crate::polydat_node(category = Conversions)]
608fn __f16_to_json(f: half::f16) -> Arc<serde_json::Value> {
609 let n = serde_json::Number::from_f64(f.to_f64()).unwrap_or_else(|| {
610 panic!("__f16_to_json: non-finite f16 {f} not representable as JSON number")
611 });
612 Arc::new(serde_json::Value::Number(n))
613}
614
615#[crate::polydat_node(category = Conversions)]
616fn __json_to_u8(j: &serde_json::Value) -> u8 {
617 let n = j
618 .as_u64()
619 .unwrap_or_else(|| panic!("__json_to_u8: JSON value {j} is not a u64"));
620 if n > u8::MAX as u64 {
621 panic!("__json_to_u8: value {n} exceeds u8::MAX ({})", u8::MAX);
622 }
623 n as u8
624}
625
626#[crate::polydat_node(category = Conversions)]
627fn __json_to_u16(j: &serde_json::Value) -> u16 {
628 let n = j
629 .as_u64()
630 .unwrap_or_else(|| panic!("__json_to_u16: JSON value {j} is not a u64"));
631 if n > u16::MAX as u64 {
632 panic!("__json_to_u16: value {n} exceeds u16::MAX ({})", u16::MAX);
633 }
634 n as u16
635}
636
637#[crate::polydat_node(category = Conversions)]
638fn __json_to_i8(j: &serde_json::Value) -> i8 {
639 let n = j
640 .as_i64()
641 .unwrap_or_else(|| panic!("__json_to_i8: JSON value {j} is not an i64"));
642 if !(i8::MIN as i64..=i8::MAX as i64).contains(&n) {
643 panic!(
644 "__json_to_i8: value {n} out of i8 range [{}, {}]",
645 i8::MIN,
646 i8::MAX
647 );
648 }
649 n as i8
650}
651
652#[crate::polydat_node(category = Conversions)]
653fn __json_to_i16(j: &serde_json::Value) -> i16 {
654 let n = j
655 .as_i64()
656 .unwrap_or_else(|| panic!("__json_to_i16: JSON value {j} is not an i64"));
657 if !(i16::MIN as i64..=i16::MAX as i64).contains(&n) {
658 panic!(
659 "__json_to_i16: value {n} out of i16 range [{}, {}]",
660 i16::MIN,
661 i16::MAX
662 );
663 }
664 n as i16
665}
666
667#[crate::polydat_node(category = Conversions)]
668fn __json_to_f16(j: &serde_json::Value) -> half::f16 {
669 let f = j
670 .as_f64()
671 .unwrap_or_else(|| panic!("__json_to_f16: JSON value {j} is not an f64"));
672 half::f16::from_f64(f)
673}
674
675#[cfg(test)]
680mod tests {
681 use super::*;
682 use crate::ast::{PolydatNode, Value};
683
684 fn check<N: PolydatNode>(node: &N, input: Value, expected: Value) {
685 let mut out = [Value::None];
686 node.eval(&[input], &mut out);
687 assert_eq!(
688 out[0],
689 expected,
690 "{} produced wrong output",
691 node.meta().name
692 );
693 }
694
695 fn check_panics<N: PolydatNode>(node: &N, input: Value, msg_substring: &str) {
696 let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
697 let mut out = [Value::None];
698 node.eval(&[input], &mut out);
699 }));
700 match result {
701 Ok(_) => panic!("{} did not panic as expected", node.meta().name),
702 Err(payload) => {
703 let s = payload
704 .downcast_ref::<String>()
705 .cloned()
706 .or_else(|| payload.downcast_ref::<&str>().map(|s| s.to_string()))
707 .unwrap_or_default();
708 assert!(
709 s.contains(msg_substring),
710 "{} panicked but message didn't contain {msg_substring:?}: {s}",
711 node.meta().name
712 );
713 }
714 }
715 }
716
717 fn f16_value(f: f32) -> Value {
720 Value::U64(half::f16::from_f32(f).to_bits() as u64)
721 }
722
723 #[test]
724 fn narrow_widenings() {
725 check(&U8ToU64::new(), Value::U64(200), Value::U64(200));
726 check(&U8ToU16::new(), Value::U64(200), Value::U64(200));
727 check(&U16ToU64::new(), Value::U64(60_000), Value::U64(60_000));
728 check(&U8ToF64::new(), Value::U64(7), Value::F64(7.0));
729 check(&I8ToI64::new(), Value::I64(-100), Value::I64(-100));
730 check(&I8ToI16::new(), Value::I64(-100), Value::I64(-100));
731 check(&I16ToI64::new(), Value::I64(-30_000), Value::I64(-30_000));
732 check(&I16ToF64::new(), Value::I64(-5), Value::F64(-5.0));
733 check(&F16ToF64::new(), f16_value(1.5), Value::F64(1.5));
734 check(
735 &F16ToF32::new(),
736 f16_value(1.5),
737 Value::U64(1.5f32.to_bits() as u64),
738 );
739 }
740
741 #[test]
742 fn narrow_narrowings_and_range_panics() {
743 check(&U64ToU8::new(), Value::U64(255), Value::U64(255));
744 check_panics(&U64ToU8::new(), Value::U64(256), "exceeds u8::MAX");
745 check(&U64ToU16::new(), Value::U64(65_535), Value::U64(65_535));
746 check_panics(&U64ToU16::new(), Value::U64(65_536), "exceeds u16::MAX");
747 check(&I64ToI8::new(), Value::I64(-128), Value::I64(-128));
748 check_panics(&I64ToI8::new(), Value::I64(128), "out of i8 range");
749 check(&I64ToI16::new(), Value::I64(-32_768), Value::I64(-32_768));
750 check_panics(&I64ToI16::new(), Value::I64(32_768), "out of i16 range");
751 check_panics(&I64ToU8::new(), Value::I64(-1), "out of u8 range");
752 check_panics(&F64ToI8::new(), Value::F64(f64::NAN), "non-finite");
753 check(&F64ToI8::new(), Value::F64(-5.9), Value::I64(-5));
754 check(&F64ToU16::new(), Value::F64(42.7), Value::U64(42));
755 check(&F64ToF16::new(), Value::F64(1.5), f16_value(1.5));
757 }
758
759 #[test]
760 fn narrow_str_parses() {
761 check(&StrToU8::new(), Value::Str("200".into()), Value::U64(200));
762 check(
763 &StrToU16::new(),
764 Value::Str(" 60000 ".into()),
765 Value::U64(60_000),
766 );
767 check(&StrToI8::new(), Value::Str("-100".into()), Value::I64(-100));
768 check(
769 &StrToI16::new(),
770 Value::Str("-30000".into()),
771 Value::I64(-30_000),
772 );
773 check(&StrToF16::new(), Value::Str("1.5".into()), f16_value(1.5));
774 check_panics(&StrToU8::new(), Value::Str("256".into()), "cannot parse");
775 check_panics(&StrToI8::new(), Value::Str("xyz".into()), "cannot parse");
776 }
777
778 #[test]
779 fn narrow_bytes_round_trip() {
780 check(
781 &U8ToBytes::new(),
782 Value::U64(0xAB),
783 Value::Bytes(vec![0xAB].into()),
784 );
785 check(
786 &BytesToU8::new(),
787 Value::Bytes(vec![0xAB].into()),
788 Value::U64(0xAB),
789 );
790 check_panics(
791 &BytesToU8::new(),
792 Value::Bytes(vec![1, 2].into()),
793 "expected exactly 1 byte",
794 );
795 check(
796 &I16ToBytes::new(),
797 Value::I64(-2),
798 Value::Bytes((-2i16).to_le_bytes().to_vec().into()),
799 );
800 check(
801 &BytesToI16::new(),
802 Value::Bytes((-2i16).to_le_bytes().to_vec().into()),
803 Value::I64(-2),
804 );
805 let f16_bytes = half::f16::from_f32(1.5).to_bits().to_le_bytes().to_vec();
806 check(
807 &F16ToBytes::new(),
808 f16_value(1.5),
809 Value::Bytes(f16_bytes.clone().into()),
810 );
811 check(
812 &BytesToF16::new(),
813 Value::Bytes(f16_bytes.into()),
814 f16_value(1.5),
815 );
816 }
817
818 #[test]
819 fn narrow_json_and_bool() {
820 check(
821 &I8ToJson::new(),
822 Value::I64(-5),
823 Value::Json(Arc::new(serde_json::Value::from(-5_i64))),
824 );
825 check(
826 &JsonToI8::new(),
827 Value::Json(Arc::new(serde_json::Value::from(-5_i64))),
828 Value::I64(-5),
829 );
830 check_panics(
831 &JsonToU8::new(),
832 Value::Json(Arc::new(serde_json::Value::from(300_u64))),
833 "exceeds u8::MAX",
834 );
835 check(&BoolToI8::new(), Value::Bool(true), Value::I64(1));
836 check(&BoolToF16::new(), Value::Bool(true), f16_value(1.0));
837 check(&I16ToBool::new(), Value::I64(-1), Value::Bool(true));
838 check(&F16ToBool::new(), f16_value(0.0), Value::Bool(false));
839 check(&F16ToBool::new(), f16_value(2.5), Value::Bool(true));
840 }
841
842 #[test]
843 fn narrow_string_renders() {
844 check(&I8ToString::new(), Value::I64(-7), Value::Str("-7".into()));
845 check(
846 &U16ToString::new(),
847 Value::U64(60_000),
848 Value::Str("60000".into()),
849 );
850 check(
853 &F16ToString::new(),
854 f16_value(1.0),
855 Value::Str("1.0".into()),
856 );
857 }
858}