1use dyn_clone::DynClone;
2use num_complex::Complex32;
3use serde::{Deserialize, Serialize};
4use std::any::Any;
5use std::collections::HashMap;
6use std::fmt;
7use thiserror::Error;
8
9pub trait PmtAny: Any + DynClone + Send + Sync + 'static {
13 fn as_any(&self) -> &dyn Any;
15 fn as_any_mut(&mut self) -> &mut dyn Any;
17}
18dyn_clone::clone_trait_object!(PmtAny);
19
20impl<T: Any + DynClone + Send + Sync + 'static> PmtAny for T {
21 fn as_any(&self) -> &dyn Any {
22 self
23 }
24 fn as_any_mut(&mut self) -> &mut dyn Any {
25 self
26 }
27}
28
29impl fmt::Debug for Box<dyn PmtAny> {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 write!(f, "Box<dyn Any>")
32 }
33}
34
35impl dyn PmtAny {
36 pub fn downcast_ref<T: PmtAny>(&self) -> Option<&T> {
38 (*self).as_any().downcast_ref::<T>()
39 }
40 pub fn downcast_mut<T: PmtAny>(&mut self) -> Option<&mut T> {
42 (*self).as_any_mut().downcast_mut::<T>()
43 }
44}
45
46#[non_exhaustive]
51#[derive(Debug, Clone, Serialize, Deserialize)]
52pub enum Pmt {
53 Ok,
55 InvalidValue,
60 Null,
65 String(String),
67 Bool(bool),
69 Usize(usize),
71 Isize(isize),
73 U32(u32),
75 U64(u64),
77 F32(f32),
79 F64(f64),
81 VecCF32(Vec<Complex32>),
83 VecF32(Vec<f32>),
85 VecU64(Vec<u64>),
87 Blob(Vec<u8>),
89 VecPmt(Vec<Pmt>),
91 Finished,
95 MapStrPmt(HashMap<String, Pmt>),
97 #[serde(skip)]
102 Any(Box<dyn PmtAny>),
103}
104
105impl fmt::Display for Pmt {
106 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107 match self {
108 Pmt::Ok => write!(f, "Ok"),
109 Pmt::InvalidValue => write!(f, "InvalidValue"),
110 Pmt::Null => write!(f, "Null"),
111 Pmt::String(v) => write!(f, "{}", v),
112 Pmt::Bool(v) => write!(f, "{}", v),
113 Pmt::Usize(v) => write!(f, "{}", v),
114 Pmt::Isize(v) => write!(f, "{}", v),
115 Pmt::U32(v) => write!(f, "{}", v),
116 Pmt::U64(v) => write!(f, "{}", v),
117 Pmt::F32(v) => write!(f, "{}", v),
118 Pmt::F64(v) => write!(f, "{}", v),
119 Pmt::VecCF32(v) => write!(f, "{:?}", v),
120 Pmt::VecF32(v) => write!(f, "{:?}", v),
121 Pmt::VecU64(v) => write!(f, "{:?}", v),
122 Pmt::Blob(v) => write!(f, "{:?}", v),
123 Pmt::VecPmt(v) => write!(f, "{:?}", v),
124 Pmt::Finished => write!(f, "Finished"),
125 Pmt::MapStrPmt(v) => write!(f, "{:?}", v),
126 Pmt::Any(v) => write!(f, "{:?}", v),
127 }
128 }
129}
130
131impl PartialEq for Pmt {
132 fn eq(&self, other: &Self) -> bool {
133 match (self, other) {
134 (Pmt::Ok, Pmt::Ok) => true,
135 (Pmt::InvalidValue, Pmt::InvalidValue) => true,
136 (Pmt::Null, Pmt::Null) => true,
137 (Pmt::String(x), Pmt::String(y)) => x == y,
138 (Pmt::Bool(x), Pmt::Bool(y)) => x == y,
139 (Pmt::Usize(x), Pmt::Usize(y)) => x == y,
140 (Pmt::Isize(x), Pmt::Isize(y)) => x == y,
141 (Pmt::U32(x), Pmt::U32(y)) => x == y,
142 (Pmt::U64(x), Pmt::U64(y)) => x == y,
143 (Pmt::F32(x), Pmt::F32(y)) => x == y,
144 (Pmt::F64(x), Pmt::F64(y)) => x == y,
145 (Pmt::VecF32(x), Pmt::VecF32(y)) => x == y,
146 (Pmt::VecU64(x), Pmt::VecU64(y)) => x == y,
147 (Pmt::Blob(x), Pmt::Blob(y)) => x == y,
148 (Pmt::VecPmt(x), Pmt::VecPmt(y)) => x == y,
149 (Pmt::Finished, Pmt::Finished) => true,
150 (Pmt::MapStrPmt(x), Pmt::MapStrPmt(y)) => x == y,
151 _ => false,
152 }
153 }
154}
155
156impl std::str::FromStr for Pmt {
157 type Err = PmtConversionError;
158
159 fn from_str(s: &str) -> Result<Self, Self::Err> {
160 match s {
161 "Ok" | "ok" => return Ok(Pmt::Ok),
162 "Null" | "null" => return Ok(Pmt::Null),
163 "true" => return Ok(Pmt::Bool(true)),
164 "false" => return Ok(Pmt::Bool(false)),
165 "InvalidValue" | "invalidvalue" => return Ok(Pmt::InvalidValue),
166 "Finished" | "finished" => return Ok(Pmt::Finished),
167 _ => (),
168 }
169
170 if let Ok(p) = serde_json::from_str(s) {
171 return Ok(p);
172 }
173
174 if let Some((a, b)) = s.split_once(':') {
175 let s = format!("{{ \"{}\": {}}}", a, b);
176 if let Ok(p) = serde_json::from_str(&s) {
177 return Ok(p);
178 }
179 }
180 Err(PmtConversionError)
181 }
182}
183
184impl Pmt {
185 pub fn from_string(s: &str, t: &PmtKind) -> Option<Pmt> {
187 match t {
188 PmtKind::U32 => {
189 if let Ok(v) = s.parse::<u32>() {
190 Some(Pmt::U32(v))
191 } else {
192 None
193 }
194 }
195 PmtKind::U64 => {
196 if let Ok(v) = s.parse::<u64>() {
197 Some(Pmt::U64(v))
198 } else {
199 None
200 }
201 }
202 PmtKind::F32 => {
203 if let Ok(v) = s.parse::<f32>() {
204 Some(Pmt::F32(v))
205 } else {
206 None
207 }
208 }
209 PmtKind::F64 => {
210 if let Ok(v) = s.parse::<f64>() {
211 Some(Pmt::F64(v))
212 } else {
213 None
214 }
215 }
216 PmtKind::String => Some(Pmt::String(s.to_string())),
217 _ => None,
218 }
219 }
220}
221
222#[derive(Debug, Clone, Error, PartialEq)]
226#[error("PMt conversion error")]
227pub struct PmtConversionError;
228
229impl TryInto<f64> for Pmt {
230 type Error = PmtConversionError;
231
232 fn try_into(self) -> Result<f64, Self::Error> {
233 match self {
234 Pmt::F32(f) => Ok(f as f64),
235 Pmt::F64(f) => Ok(f),
236 Pmt::U32(f) => Ok(f as f64),
237 Pmt::U64(f) => Ok(f as f64),
238 _ => Err(PmtConversionError),
239 }
240 }
241}
242
243impl TryInto<usize> for Pmt {
244 type Error = PmtConversionError;
245
246 fn try_into(self) -> Result<usize, Self::Error> {
247 match self {
248 Pmt::Usize(f) => Ok(f),
249 _ => Err(PmtConversionError),
250 }
251 }
252}
253
254impl TryInto<isize> for Pmt {
255 type Error = PmtConversionError;
256
257 fn try_into(self) -> Result<isize, Self::Error> {
258 match self {
259 Pmt::Isize(f) => Ok(f),
260 _ => Err(PmtConversionError),
261 }
262 }
263}
264
265impl TryInto<u64> for Pmt {
266 type Error = PmtConversionError;
267
268 fn try_into(self) -> Result<u64, Self::Error> {
269 match self {
270 Pmt::U32(v) => Ok(v as u64),
271 Pmt::U64(v) => Ok(v),
272 Pmt::Usize(v) => Ok(v as u64),
273 _ => Err(PmtConversionError),
274 }
275 }
276}
277
278#[non_exhaustive]
282#[derive(Clone, PartialEq, Eq)]
283pub enum PmtKind {
284 Ok,
286 InvalidValue,
288 Null,
290 String,
292 Bool,
294 Usize,
296 Isize,
298 U32,
300 U64,
302 F32,
304 F64,
306 VecCF32,
308 VecF32,
310 VecU64,
312 Blob,
314 VecPmt,
316 Finished,
318 MapStrPmt,
320 Any,
322}
323
324impl fmt::Display for PmtKind {
325 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
326 match self {
327 PmtKind::Ok => write!(f, "Ok"),
328 PmtKind::InvalidValue => write!(f, "InvalidValue"),
329 PmtKind::Null => write!(f, "Null"),
330 PmtKind::String => write!(f, "String"),
331 PmtKind::Bool => write!(f, "Bool"),
332 PmtKind::Usize => write!(f, "Usize"),
333 PmtKind::Isize => write!(f, "isize"),
334 PmtKind::U32 => write!(f, "U32"),
335 PmtKind::U64 => write!(f, "U64"),
336 PmtKind::F32 => write!(f, "F32"),
337 PmtKind::F64 => write!(f, "F64"),
338 PmtKind::VecCF32 => write!(f, "VecCF32"),
339 PmtKind::VecF32 => write!(f, "VecF32"),
340 PmtKind::VecU64 => write!(f, "VecU64"),
341 PmtKind::Blob => write!(f, "Blob"),
342 PmtKind::VecPmt => write!(f, "VecPmt"),
343 PmtKind::Finished => write!(f, "Finished"),
344 PmtKind::MapStrPmt => write!(f, "MapStrPmt"),
345 PmtKind::Any => write!(f, "Any"),
346 }
347 }
348}
349
350impl std::str::FromStr for PmtKind {
351 type Err = PmtConversionError;
352
353 fn from_str(s: &str) -> Result<Self, Self::Err> {
354 match s {
355 "Ok" => return Ok(PmtKind::Ok),
356 "InvalidValue" => return Ok(PmtKind::InvalidValue),
357 "Null" => return Ok(PmtKind::Null),
358 "String" => return Ok(PmtKind::String),
359 "Bool" => return Ok(PmtKind::Bool),
360 "Usize" => return Ok(PmtKind::Usize),
361 "Isize" => return Ok(PmtKind::Isize),
362 "U32" => return Ok(PmtKind::U32),
363 "U64" => return Ok(PmtKind::U64),
364 "F32" => return Ok(PmtKind::F32),
365 "F64" => return Ok(PmtKind::F64),
366 "VecF32" => return Ok(PmtKind::VecF32),
367 "VecU64" => return Ok(PmtKind::VecU64),
368 "Blob" => return Ok(PmtKind::Blob),
369 "VecPmt" => return Ok(PmtKind::VecPmt),
370 "Finished" => return Ok(PmtKind::Finished),
371 "MapStrPmt" => return Ok(PmtKind::MapStrPmt),
372 "Any" => return Ok(PmtKind::Any),
373 _ => (),
374 }
375 Err(PmtConversionError)
376 }
377}
378
379#[cfg(test)]
380mod test {
381 use super::*;
382
383 #[test]
384 fn pmt() {
385 let p = Pmt::Null;
386 assert_eq!(p.to_string(), "Null");
387 let p = Pmt::String("foo".to_string());
388 assert_eq!(p.to_string(), "foo");
389 }
390
391 #[test]
392 fn pmt_parse_json() {
393 let s = "{ \"U32\": 123 }";
394 assert_eq!(s.parse::<Pmt>(), Ok(Pmt::U32(123)));
395 let s = "{ \"Bool\": true }";
396 assert_eq!(s.parse::<Pmt>(), Ok(Pmt::Bool(true)));
397 let s = "Bool: true";
398 assert_eq!(s.parse::<Pmt>(), Ok(Pmt::Bool(true)));
399 let s = "U32: 123";
400 assert_eq!(s.parse::<Pmt>(), Ok(Pmt::U32(123)));
401 let s = "F64: 123";
402 assert_eq!(s.parse::<Pmt>(), Ok(Pmt::F64(123.0)));
403 let s = "Blob: [1,2,3]";
404 assert_eq!(s.parse::<Pmt>(), Ok(Pmt::Blob(vec![1, 2, 3])));
405 }
406
407 #[test]
408 fn pmt_serde() {
409 let p = Pmt::Null;
410 let mut s = flexbuffers::FlexbufferSerializer::new();
411 p.serialize(&mut s).unwrap();
412
413 let r = flexbuffers::Reader::get_root(s.view()).unwrap();
414 let p2 = Pmt::deserialize(r).unwrap();
415
416 assert_eq!(p, p2);
417 }
418
419 #[allow(clippy::many_single_char_names)]
420 #[test]
421 fn pmt_eq() {
422 let a = Pmt::Null;
423 let b = Pmt::U32(123);
424 assert_ne!(a, b);
425
426 let c = Pmt::Null;
427 let d = Pmt::U32(12);
428 let e = Pmt::U32(123);
429 assert_eq!(a, c);
430 assert_eq!(b, e);
431 assert_ne!(b, d);
432
433 let f1 = Pmt::F32(0.1);
434 let f2 = Pmt::F32(0.1);
435 let f3 = Pmt::F32(0.2);
436 assert_eq!(f1, f2);
437 assert_ne!(f1, f3);
438 }
439
440 #[test]
441 fn vec_pmt() {
442 let vpmt = Pmt::VecPmt(vec![Pmt::U32(1), Pmt::U32(2)]);
443
444 if let Pmt::VecPmt(v) = vpmt {
445 assert_eq!(v[0], Pmt::U32(1));
446 assert_eq!(v[1], Pmt::U32(2));
447 } else {
448 panic!("Not a Pmt::VecPmt");
449 }
450 }
451
452 #[test]
453 fn map_str_pmt() {
454 let u32val = 42;
455 let f64val = 6.02214076e23;
456
457 let msp = Pmt::MapStrPmt(HashMap::from([
458 ("str".to_owned(), Pmt::String("a string".to_owned())),
459 (
460 "submap".to_owned(),
461 Pmt::MapStrPmt(HashMap::from([
462 ("U32".to_owned(), Pmt::U32(u32val)),
463 ("F64".to_owned(), Pmt::F64(f64val)),
464 ])),
465 ),
466 ]));
467
468 if let Pmt::MapStrPmt(m) = msp {
469 if let Some(Pmt::MapStrPmt(sm)) = m.get("submap") {
470 assert_eq!(sm.get("U32"), Some(&Pmt::U32(u32val)));
471 assert_eq!(sm.get("F64"), Some(&Pmt::F64(f64val)));
472 } else {
473 panic!("Could not get submap");
474 }
475 } else {
476 panic!("Not a Pmt::MapStrPmt");
477 }
478 }
479}