1macro_rules! int_narrow {
29 ( $( $from:ident $fty:ty => $( $to:ident $tty:ty ),+ );+ $(;)? ) => {
30 paste::paste! { $( $(
31 #[crate::polydat_node(category = Conversions)]
32 fn [<__ $from _to_ $to>](n: $fty) -> $tty {
33 <$tty>::try_from(n).unwrap_or_else(|_| panic!(
34 concat!(stringify!([<__ $from _to_ $to>]),
35 ": value {} out of ", stringify!($tty), " range"), n))
36 }
37 )+ )+ }
38 };
39}
40
41int_narrow! {
42 u8 u8 => i8 i8;
43 i8 i8 => u8 u8, u16 u16, u32 u32, u64 u64, u128 u128;
44 u16 u16 => i8 i8, i16 i16;
45 i16 i16 => u8 u8, i8 i8, u16 u16, u32 u32, u64 u64, u128 u128;
46 u32 u32 => i8 i8, i16 i16;
47 i32 i32 => u8 u8, u16 u16, u128 u128;
48 u128 u128 => u8 u8, i8 i8, u16 u16, i16 i16, u32 u32, i32 i32, i64 i64;
49 i128 i128 => u8 u8, i8 i8, u16 u16, i16 i16, u32 u32, i32 i32, u64 u64;
50}
51
52macro_rules! int_to_narrow_float {
55 ( f16 : $( $from:ident $fty:ty ),+ ) => {
56 paste::paste! { $(
57 #[crate::polydat_node(category = Conversions)]
58 fn [<__ $from _to_f16>](n: $fty) -> half::f16 { half::f16::from_f64(n as f64) }
59 )+ }
60 };
61 ( f32 : $( $from:ident $fty:ty ),+ ) => {
62 paste::paste! { $(
63 #[crate::polydat_node(category = Conversions)]
64 fn [<__ $from _to_f32>](n: $fty) -> f32 { n as f32 }
65 )+ }
66 };
67}
68
69int_to_narrow_float!(f16: u16 u16, i16 i16, u32 u32, i32 i32, i64 i64, u128 u128, i128 i128);
70int_to_narrow_float!(f32: u128 u128, i128 i128);
71
72macro_rules! float_to_int {
75 ( $from:ident $fty:ty | $to_f64:expr ; $( $to:ident $tty:ty ),+ ) => {
76 paste::paste! { $(
77 #[crate::polydat_node(category = Conversions)]
78 fn [<__ $from _to_ $to>](n: $fty) -> $tty {
79 let v: f64 = $to_f64(n);
80 if !v.is_finite() || v < <$tty>::MIN as f64 || v > <$tty>::MAX as f64 {
81 panic!(concat!(stringify!([<__ $from _to_ $to>]),
82 ": value {} out of ", stringify!($tty), " range or non-finite"), v);
83 }
84 v as $tty
85 }
86 )+ }
87 };
88}
89
90float_to_int!(f16 half::f16 | (|n: half::f16| n.to_f64()) ;
91 u8 u8, i8 i8, u16 u16, i16 i16, u32 u32, i32 i32, u64 u64, i64 i64, u128 u128, i128 i128);
92float_to_int!(f32 f32 | (|n: f32| n as f64) ;
93 u8 u8, i8 i8, u16 u16, i16 i16, u128 u128, i128 i128);
94
95macro_rules! vec_as {
105 ( $( $from:ident $fe:ty => $( $to:ident $te:ty ),+ );+ $(;)? ) => {
106 paste::paste! { $( $(
107 #[crate::polydat_node(category = Conversions)]
108 fn [<__ vec_ $from _to_vec_ $to>](elems: &[$fe]) -> Vec<$te> {
109 elems.iter().map(|&x| x as $te).collect()
110 }
111 )+ )+ }
112 };
113}
114
115macro_rules! vec_narrow_int {
117 ( $( $from:ident $fe:ty => $( $to:ident $te:ty ),+ );+ $(;)? ) => {
118 paste::paste! { $( $(
119 #[crate::polydat_node(category = Conversions)]
120 fn [<__ vec_ $from _to_vec_ $to>](elems: &[$fe]) -> Vec<$te> {
121 elems.iter().map(|&x| <$te>::try_from(x).unwrap_or_else(|_| panic!(
122 concat!("__vec_", stringify!($from), "_to_vec_", stringify!($to),
123 ": element {} out of ", stringify!($te), " range"), x))).collect()
124 }
125 )+ )+ }
126 };
127}
128
129macro_rules! vec_float_to_int {
131 ( $from:ident $fe:ty => $( $to:ident $te:ty ),+ ) => {
132 paste::paste! { $(
133 #[crate::polydat_node(category = Conversions)]
134 fn [<__ vec_ $from _to_vec_ $to>](elems: &[$fe]) -> Vec<$te> {
135 elems.iter().map(|&x| {
136 let v = x as f64;
137 if !v.is_finite() || v < <$te>::MIN as f64 || v > <$te>::MAX as f64 {
138 panic!(concat!("__vec_", stringify!($from), "_to_vec_", stringify!($to),
139 ": element {} out of ", stringify!($te), " range or non-finite"), v);
140 }
141 v as $te
142 }).collect()
143 }
144 )+ }
145 };
146}
147
148macro_rules! vec_f16_to_int {
150 ( $( $to:ident $te:ty ),+ ) => {
151 paste::paste! { $(
152 #[crate::polydat_node(category = Conversions)]
153 fn [<__ vec_f16_to_vec_ $to>](elems: &[half::f16]) -> Vec<$te> {
154 elems.iter().map(|&x| {
155 let v = x.to_f64();
156 if !v.is_finite() || v < <$te>::MIN as f64 || v > <$te>::MAX as f64 {
157 panic!(concat!("__vec_f16_to_vec_", stringify!($to),
158 ": element {} out of ", stringify!($te), " range or non-finite"), v);
159 }
160 v as $te
161 }).collect()
162 }
163 )+ }
164 };
165}
166
167macro_rules! vec_to_f16 {
169 ( $( $from:ident $fe:ty ),+ ) => {
170 paste::paste! { $(
171 #[crate::polydat_node(category = Conversions)]
172 fn [<__ vec_ $from _to_vec_f16>](elems: &[$fe]) -> Vec<half::f16> {
173 elems.iter().map(|&x| half::f16::from_f64(x as f64)).collect()
174 }
175 )+ }
176 };
177}
178
179vec_as! {
180 f32 f32 => f64 f64;
181 i32 i32 => f64 f64, i64 i64;
182 f64 f64 => f32 f32;
183 i64 i64 => f32 f32, f64 f64;
184 i16 i16 => f32 f32, i32 i32, f64 f64, i64 i64;
185 i8 i8 => f32 f32, i32 i32, f64 f64, i64 i64, i16 i16;
186}
187vec_narrow_int! {
188 i32 i32 => i16 i16, i8 i8;
189 i64 i64 => i32 i32, i16 i16, i8 i8;
190 i16 i16 => i8 i8;
191}
192vec_float_to_int!(f32 f32 => i64 i64, i16 i16, i8 i8);
193vec_float_to_int!(f64 f64 => i32 i32, i64 i64, i16 i16, i8 i8);
194vec_f16_to_int!(i32 i32, i64 i64, i16 i16, i8 i8);
195vec_to_f16!(f32 f32, i32 i32, f64 f64, i64 i64, i16 i16, i8 i8);
196
197#[crate::polydat_node(category = Conversions)]
198fn __vec_f16_to_vec_f32(elems: &[half::f16]) -> Vec<f32> {
199 elems.iter().map(|&x| x.to_f32()).collect()
200}
201#[crate::polydat_node(category = Conversions)]
202fn __vec_f16_to_vec_f64(elems: &[half::f16]) -> Vec<f64> {
203 elems.iter().map(|&x| x.to_f64()).collect()
204}
205
206use std::sync::Arc;
215
216macro_rules! vec_to_bytes {
218 ( $( $from:ident $fe:ty ),+ ) => {
219 paste::paste! { $(
220 #[crate::polydat_node(category = Conversions)]
221 fn [<__ vec_ $from _to_bytes>](elems: &[$fe]) -> Vec<u8> {
222 let mut buf = Vec::with_capacity(elems.len() * std::mem::size_of::<$fe>());
223 for &v in elems { buf.extend_from_slice(&v.to_le_bytes()); }
224 buf
225 }
226 )+ }
227 };
228}
229vec_to_bytes!(f64 f64, i64 i64, i16 i16, i8 i8);
230
231#[crate::polydat_node(category = Conversions)]
232fn __vec_f16_to_bytes(elems: &[half::f16]) -> Vec<u8> {
233 let mut buf = Vec::with_capacity(elems.len() * 2);
234 for &v in elems {
235 buf.extend_from_slice(&v.to_bits().to_le_bytes());
236 }
237 buf
238}
239
240macro_rules! bytes_to_vec {
242 ( $( $to:ident $te:ty ),+ ) => {
243 paste::paste! { $(
244 #[crate::polydat_node(category = Conversions)]
245 fn [<__ bytes_to_vec_ $to>](b: &[u8]) -> Vec<$te> {
246 let n = std::mem::size_of::<$te>();
247 if b.len() % n != 0 {
248 panic!(concat!("__bytes_to_vec_", stringify!($to),
249 ": byte length {} is not a multiple of the element size"), b.len());
250 }
251 b.chunks_exact(n).map(|c| <$te>::from_le_bytes(c.try_into().unwrap())).collect()
252 }
253 )+ }
254 };
255}
256bytes_to_vec!(f64 f64, i64 i64, i16 i16, i8 i8);
257
258#[crate::polydat_node(category = Conversions)]
259fn __bytes_to_vec_f16(b: &[u8]) -> Vec<half::f16> {
260 if !b.len().is_multiple_of(2) {
261 panic!(
262 "__bytes_to_vec_f16: byte length {} is not a multiple of 2",
263 b.len()
264 );
265 }
266 b.as_chunks::<2>()
267 .0
268 .iter()
269 .map(|c| half::f16::from_bits(u16::from_le_bytes(*c)))
270 .collect()
271}
272
273macro_rules! vec_int_to_json {
275 ( $( $from:ident $fe:ty ),+ ) => {
276 paste::paste! { $(
277 #[crate::polydat_node(category = Conversions)]
278 fn [<__ vec_ $from _to_json>](elems: &[$fe]) -> Arc<serde_json::Value> {
279 let arr: Vec<serde_json::Value> = elems.iter()
280 .map(|&v| serde_json::Value::Number(serde_json::Number::from(v)))
281 .collect();
282 Arc::new(serde_json::Value::Array(arr))
283 }
284 )+ }
285 };
286}
287vec_int_to_json!(i64 i64, i16 i16, i8 i8);
288
289#[crate::polydat_node(category = Conversions)]
290fn __vec_f64_to_json(elems: &[f64]) -> Arc<serde_json::Value> {
291 let arr: Vec<serde_json::Value> = elems
292 .iter()
293 .map(|&v| {
294 serde_json::Value::Number(
295 serde_json::Number::from_f64(v)
296 .unwrap_or_else(|| panic!("__vec_f64_to_json: non-finite element {v}")),
297 )
298 })
299 .collect();
300 Arc::new(serde_json::Value::Array(arr))
301}
302#[crate::polydat_node(category = Conversions)]
303fn __vec_f16_to_json(elems: &[half::f16]) -> Arc<serde_json::Value> {
304 let arr: Vec<serde_json::Value> = elems
305 .iter()
306 .map(|&v| {
307 let f = v.to_f64();
308 serde_json::Value::Number(
309 serde_json::Number::from_f64(f)
310 .unwrap_or_else(|| panic!("__vec_f16_to_json: non-finite element {f}")),
311 )
312 })
313 .collect();
314 Arc::new(serde_json::Value::Array(arr))
315}
316
317macro_rules! vec_int_to_str {
319 ( $( $from:ident $fe:ty ),+ ) => {
320 paste::paste! { $(
321 #[crate::polydat_node(category = Conversions)]
322 fn [<__ vec_ $from _to_str>](elems: &[$fe]) -> String {
323 let arr: Vec<serde_json::Value> = elems.iter()
324 .map(|&v| serde_json::Value::Number(serde_json::Number::from(v)))
325 .collect();
326 serde_json::Value::Array(arr).to_string()
327 }
328 )+ }
329 };
330}
331vec_int_to_str!(i64 i64, i16 i16, i8 i8);
333
334#[crate::polydat_node(category = Conversions)]
335fn __vec_f64_to_str(elems: &[f64]) -> String {
336 let arr: Vec<serde_json::Value> = elems
337 .iter()
338 .map(|&v| {
339 serde_json::Value::Number(
340 serde_json::Number::from_f64(v)
341 .unwrap_or_else(|| panic!("__vec_f64_to_str: non-finite element {v}")),
342 )
343 })
344 .collect();
345 serde_json::Value::Array(arr).to_string()
346}
347#[crate::polydat_node(category = Conversions)]
348fn __vec_f16_to_str(elems: &[half::f16]) -> String {
349 let arr: Vec<serde_json::Value> = elems
350 .iter()
351 .map(|&v| {
352 let f = v.to_f64();
353 serde_json::Value::Number(
354 serde_json::Number::from_f64(f)
355 .unwrap_or_else(|| panic!("__vec_f16_to_str: non-finite element {f}")),
356 )
357 })
358 .collect();
359 serde_json::Value::Array(arr).to_string()
360}
361
362macro_rules! json_to_vec_int {
364 ( $( $to:ident $te:ty ),+ ) => {
365 paste::paste! { $(
366 #[crate::polydat_node(category = Conversions)]
367 fn [<__ json_to_vec_ $to>](j: &serde_json::Value) -> Vec<$te> {
368 let arr = j.as_array().unwrap_or_else(||
369 panic!(concat!("__json_to_vec_", stringify!($to), ": JSON value is not an array")));
370 arr.iter().map(|e| {
371 let n = e.as_i64().unwrap_or_else(||
372 panic!(concat!("__json_to_vec_", stringify!($to), ": element {:?} is not an integer"), e));
373 <$te>::try_from(n).unwrap_or_else(|_|
374 panic!(concat!("__json_to_vec_", stringify!($to), ": element {} out of range"), n))
375 }).collect()
376 }
377 )+ }
378 };
379}
380json_to_vec_int!(i64 i64, i16 i16, i8 i8);
381
382#[crate::polydat_node(category = Conversions)]
383fn __json_to_vec_f64(j: &serde_json::Value) -> Vec<f64> {
384 let arr = j
385 .as_array()
386 .unwrap_or_else(|| panic!("__json_to_vec_f64: JSON value is not an array"));
387 arr.iter()
388 .map(|e| {
389 e.as_f64()
390 .unwrap_or_else(|| panic!("__json_to_vec_f64: element {e:?} is not a number"))
391 })
392 .collect()
393}
394#[crate::polydat_node(category = Conversions)]
395fn __json_to_vec_f16(j: &serde_json::Value) -> Vec<half::f16> {
396 let arr = j
397 .as_array()
398 .unwrap_or_else(|| panic!("__json_to_vec_f16: JSON value is not an array"));
399 arr.iter()
400 .map(|e| {
401 half::f16::from_f64(
402 e.as_f64()
403 .unwrap_or_else(|| panic!("__json_to_vec_f16: element {e:?} is not a number")),
404 )
405 })
406 .collect()
407}
408
409macro_rules! str_to_vec_int {
411 ( $( $to:ident $te:ty ),+ ) => {
412 paste::paste! { $(
413 #[crate::polydat_node(category = Conversions)]
414 fn [<__ str_to_vec_ $to>](input: &str) -> Vec<$te> {
415 let raw = input.trim();
416 let parsed: serde_json::Value = serde_json::from_str(raw).unwrap_or_else(|e|
417 panic!(concat!("__str_to_vec_", stringify!($to), ": cannot parse {:?} as JSON array: {}"), raw, e));
418 let arr = parsed.as_array().unwrap_or_else(||
419 panic!(concat!("__str_to_vec_", stringify!($to), ": parsed JSON is not an array: {:?}"), raw));
420 arr.iter().map(|e| {
421 let n = e.as_i64().unwrap_or_else(||
422 panic!(concat!("__str_to_vec_", stringify!($to), ": element {:?} is not an integer"), e));
423 <$te>::try_from(n).unwrap_or_else(|_|
424 panic!(concat!("__str_to_vec_", stringify!($to), ": element {} out of range"), n))
425 }).collect()
426 }
427 )+ }
428 };
429}
430str_to_vec_int!(i64 i64, i16 i16, i8 i8);
431
432#[crate::polydat_node(category = Conversions)]
433fn __str_to_vec_f64(input: &str) -> Vec<f64> {
434 let raw = input.trim();
435 let parsed: serde_json::Value = serde_json::from_str(raw)
436 .unwrap_or_else(|e| panic!("__str_to_vec_f64: cannot parse {raw:?} as JSON array: {e}"));
437 let arr = parsed
438 .as_array()
439 .unwrap_or_else(|| panic!("__str_to_vec_f64: parsed JSON is not an array: {raw:?}"));
440 arr.iter()
441 .map(|e| {
442 e.as_f64().unwrap_or_else(|| {
443 panic!("__str_to_vec_f64: element {e:?} is not a number in {raw:?}")
444 })
445 })
446 .collect()
447}
448#[crate::polydat_node(category = Conversions)]
449fn __str_to_vec_f16(input: &str) -> Vec<half::f16> {
450 let raw = input.trim();
451 let parsed: serde_json::Value = serde_json::from_str(raw)
452 .unwrap_or_else(|e| panic!("__str_to_vec_f16: cannot parse {raw:?} as JSON array: {e}"));
453 let arr = parsed
454 .as_array()
455 .unwrap_or_else(|| panic!("__str_to_vec_f16: parsed JSON is not an array: {raw:?}"));
456 arr.iter()
457 .map(|e| {
458 half::f16::from_f64(e.as_f64().unwrap_or_else(|| {
459 panic!("__str_to_vec_f16: element {e:?} is not a number in {raw:?}")
460 }))
461 })
462 .collect()
463}