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