futuresdr_types/
pmt.rs

1use dyn_clone::DynClone;
2use num_complex::Complex32;
3use serde::Deserialize;
4use serde::Serialize;
5use std::any::Any;
6use std::collections::HashMap;
7use std::fmt;
8use thiserror::Error;
9
10/// PMT Any trait
11///
12/// This trait has to be implemented by types that should be used with [`Pmt::Any`].
13pub trait PmtAny: Any + DynClone + Send + Sync + 'static {
14    /// Cast to [`Any`](std::any::Any)
15    fn as_any(&self) -> &dyn Any;
16    /// Cast to mutable [`Any`](std::any::Any)
17    fn as_any_mut(&mut self) -> &mut dyn Any;
18    /// Consume `self`, converting to a `Box<dyn Any>`
19    fn to_any(self: Box<Self>) -> Box<dyn Any>;
20}
21dyn_clone::clone_trait_object!(PmtAny);
22
23impl<T: Any + DynClone + Send + Sync + 'static> PmtAny for T {
24    fn as_any(&self) -> &dyn Any {
25        self
26    }
27    fn as_any_mut(&mut self) -> &mut dyn Any {
28        self
29    }
30    fn to_any(self: Box<Self>) -> Box<dyn Any> {
31        self
32    }
33}
34
35impl fmt::Debug for Box<dyn PmtAny> {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        write!(f, "Box<dyn Any>")
38    }
39}
40
41impl dyn PmtAny {
42    /// Determine if this `PmtAny` has the given concrete type.
43    ///
44    /// A value of `true` implies `downcast_ref`, `downcast_mut` and `take` will return `Some`.
45    pub fn is<T: PmtAny>(&self) -> bool {
46        self.as_any().is::<T>()
47    }
48    /// Try to cast the [`Pmt::Any`] to the given type.
49    pub fn downcast_ref<T: PmtAny>(&self) -> Option<&T> {
50        (*self).as_any().downcast_ref::<T>()
51    }
52    /// Try to cast the [`Pmt::Any`] to the given type mutably.
53    pub fn downcast_mut<T: PmtAny>(&mut self) -> Option<&mut T> {
54        (*self).as_any_mut().downcast_mut::<T>()
55    }
56    /// Consuming `self`, try to take ownership of the value as the given type.
57    pub fn take<T: PmtAny>(self: Box<Self>) -> Option<Box<T>> {
58        self.to_any().downcast::<T>().ok()
59    }
60}
61
62/// PMT -- Polymorphic Type
63///
64/// PMTs are used as input and output for the FutureSDR message passing interface. At the moment,
65/// the `Any` type is ignored for de-/serialization.
66#[non_exhaustive]
67#[derive(Debug, Clone, Serialize, Deserialize)]
68pub enum Pmt {
69    /// Ok.
70    Ok,
71    /// Invalid value
72    ///
73    /// Mainly used as the return type in message handlers, when the parameter is outside the
74    /// allowed range.
75    InvalidValue,
76    /// Null
77    ///
78    /// Used, for example, as the input type, when the message handler is mainly about the return
79    /// type.
80    Null,
81    /// String
82    String(String),
83    /// Boolean
84    Bool(bool),
85    /// Usize
86    Usize(usize),
87    /// Isize
88    Isize(isize),
89    /// U32, 32-bit unsigned integer
90    U32(u32),
91    /// U64, 64-bit unsigned integer
92    U64(u64),
93    /// F32, 32-bit float
94    F32(f32),
95    /// F64, 64-bit float
96    F64(f64),
97    /// Vector of 32-bit complex floats.
98    VecCF32(Vec<Complex32>),
99    /// Vector of 32-bit floats.
100    VecF32(Vec<f32>),
101    /// Vector of 64-bit floats.
102    VecU64(Vec<u64>),
103    /// Binary data blob
104    Blob(Vec<u8>),
105    /// Vector of [`Pmts`](Pmt)
106    VecPmt(Vec<Pmt>),
107    /// Finished
108    ///
109    /// Runtime message, used to signal the handler that a connected block finished.
110    Finished,
111    /// Map (String -> Pmt)
112    MapStrPmt(HashMap<String, Pmt>),
113    /// Any type
114    ///
115    /// Wrap anything that implements [`Any`](std::any::Any) in a Pmt. Use
116    /// `downcast_ref/mut()` to extract.
117    #[serde(skip)]
118    Any(Box<dyn PmtAny>),
119}
120
121impl Pmt {
122    /// Get the PMT variant kind without associated data.
123    pub fn kind(&self) -> PmtKind {
124        match self {
125            Pmt::Ok => PmtKind::Ok,
126            Pmt::InvalidValue => PmtKind::InvalidValue,
127            Pmt::Null => PmtKind::Null,
128            Pmt::String(_) => PmtKind::String,
129            Pmt::Bool(_) => PmtKind::Bool,
130            Pmt::Usize(_) => PmtKind::Usize,
131            Pmt::Isize(_) => PmtKind::Isize,
132            Pmt::U32(_) => PmtKind::U32,
133            Pmt::U64(_) => PmtKind::U64,
134            Pmt::F32(_) => PmtKind::F32,
135            Pmt::F64(_) => PmtKind::F64,
136            Pmt::VecCF32(_) => PmtKind::VecCF32,
137            Pmt::VecF32(_) => PmtKind::VecF32,
138            Pmt::VecU64(_) => PmtKind::VecU64,
139            Pmt::Blob(_) => PmtKind::Blob,
140            Pmt::VecPmt(_) => PmtKind::VecPmt,
141            Pmt::Finished => PmtKind::Finished,
142            Pmt::MapStrPmt(_) => PmtKind::MapStrPmt,
143            Pmt::Any(_) => PmtKind::Any,
144        }
145    }
146}
147
148impl fmt::Display for Pmt {
149    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150        match self {
151            Pmt::Ok => write!(f, "Ok"),
152            Pmt::InvalidValue => write!(f, "InvalidValue"),
153            Pmt::Null => write!(f, "Null"),
154            Pmt::String(v) => write!(f, "{v}"),
155            Pmt::Bool(v) => write!(f, "{v}"),
156            Pmt::Usize(v) => write!(f, "{v}"),
157            Pmt::Isize(v) => write!(f, "{v}"),
158            Pmt::U32(v) => write!(f, "{v}"),
159            Pmt::U64(v) => write!(f, "{v}"),
160            Pmt::F32(v) => write!(f, "{v}"),
161            Pmt::F64(v) => write!(f, "{v}"),
162            Pmt::VecCF32(v) => write!(f, "{v:?}"),
163            Pmt::VecF32(v) => write!(f, "{v:?}"),
164            Pmt::VecU64(v) => write!(f, "{v:?}"),
165            Pmt::Blob(v) => write!(f, "{v:?}"),
166            Pmt::VecPmt(v) => write!(f, "{v:?}"),
167            Pmt::Finished => write!(f, "Finished"),
168            Pmt::MapStrPmt(v) => write!(f, "{v:?}"),
169            Pmt::Any(v) => write!(f, "{v:?}"),
170        }
171    }
172}
173
174impl PartialEq for Pmt {
175    fn eq(&self, other: &Self) -> bool {
176        match (self, other) {
177            (Pmt::Ok, Pmt::Ok) => true,
178            (Pmt::InvalidValue, Pmt::InvalidValue) => true,
179            (Pmt::Null, Pmt::Null) => true,
180            (Pmt::String(x), Pmt::String(y)) => x == y,
181            (Pmt::Bool(x), Pmt::Bool(y)) => x == y,
182            (Pmt::Usize(x), Pmt::Usize(y)) => x == y,
183            (Pmt::Isize(x), Pmt::Isize(y)) => x == y,
184            (Pmt::U32(x), Pmt::U32(y)) => x == y,
185            (Pmt::U64(x), Pmt::U64(y)) => x == y,
186            (Pmt::F32(x), Pmt::F32(y)) => x == y,
187            (Pmt::F64(x), Pmt::F64(y)) => x == y,
188            (Pmt::VecF32(x), Pmt::VecF32(y)) => x == y,
189            (Pmt::VecU64(x), Pmt::VecU64(y)) => x == y,
190            (Pmt::VecCF32(x), Pmt::VecCF32(y)) => x == y,
191            (Pmt::Blob(x), Pmt::Blob(y)) => x == y,
192            (Pmt::VecPmt(x), Pmt::VecPmt(y)) => x == y,
193            (Pmt::Finished, Pmt::Finished) => true,
194            (Pmt::MapStrPmt(x), Pmt::MapStrPmt(y)) => x == y,
195            _ => false,
196        }
197    }
198}
199
200impl std::str::FromStr for Pmt {
201    type Err = PmtConversionError;
202
203    fn from_str(s: &str) -> Result<Self, Self::Err> {
204        match s {
205            "Ok" | "ok" => return Ok(Pmt::Ok),
206            "Null" | "null" => return Ok(Pmt::Null),
207            "true" => return Ok(Pmt::Bool(true)),
208            "false" => return Ok(Pmt::Bool(false)),
209            "InvalidValue" | "invalidvalue" => return Ok(Pmt::InvalidValue),
210            "Finished" | "finished" => return Ok(Pmt::Finished),
211            _ => (),
212        }
213
214        if let Ok(p) = serde_json::from_str(s) {
215            return Ok(p);
216        }
217
218        if let Some((a, b)) = s.split_once(':') {
219            let s = format!("{{ \"{a}\": {b}}}");
220            if let Ok(p) = serde_json::from_str(&s) {
221                return Ok(p);
222            }
223        }
224        Err(PmtConversionError)
225    }
226}
227
228impl Pmt {
229    /// Create a [`Pmt`] by parsing a string into a specific [`PmtKind`].
230    pub fn from_string(s: &str, t: &PmtKind) -> Option<Pmt> {
231        match t {
232            PmtKind::U32 => {
233                if let Ok(v) = s.parse::<u32>() {
234                    Some(Pmt::U32(v))
235                } else {
236                    None
237                }
238            }
239            PmtKind::U64 => {
240                if let Ok(v) = s.parse::<u64>() {
241                    Some(Pmt::U64(v))
242                } else {
243                    None
244                }
245            }
246            PmtKind::F32 => {
247                if let Ok(v) = s.parse::<f32>() {
248                    Some(Pmt::F32(v))
249                } else {
250                    None
251                }
252            }
253            PmtKind::F64 => {
254                if let Ok(v) = s.parse::<f64>() {
255                    Some(Pmt::F64(v))
256                } else {
257                    None
258                }
259            }
260            PmtKind::String => Some(Pmt::String(s.to_string())),
261            _ => None,
262        }
263    }
264}
265
266/// PMT conversion error.
267///
268/// This error is returned, if conversion to/from PMTs fail.
269#[derive(Debug, Clone, Error, PartialEq)]
270#[error("PMT conversion error")]
271pub struct PmtConversionError;
272
273impl TryFrom<&Pmt> for f64 {
274    type Error = PmtConversionError;
275
276    fn try_from(value: &Pmt) -> Result<f64, Self::Error> {
277        match value {
278            Pmt::F32(f) => Ok(*f as f64),
279            Pmt::F64(f) => Ok(*f),
280            Pmt::U32(f) => Ok(*f as f64),
281            Pmt::U64(f) => Ok(*f as f64),
282            _ => Err(PmtConversionError),
283        }
284    }
285}
286
287impl TryFrom<Pmt> for f64 {
288    type Error = PmtConversionError;
289
290    fn try_from(value: Pmt) -> Result<f64, Self::Error> {
291        (&value).try_into()
292    }
293}
294
295impl TryFrom<&Pmt> for usize {
296    type Error = PmtConversionError;
297
298    fn try_from(value: &Pmt) -> Result<usize, Self::Error> {
299        match value {
300            Pmt::Usize(f) => Ok(*f),
301            _ => Err(PmtConversionError),
302        }
303    }
304}
305
306impl TryFrom<Pmt> for usize {
307    type Error = PmtConversionError;
308
309    fn try_from(value: Pmt) -> Result<usize, Self::Error> {
310        (&value).try_into()
311    }
312}
313
314impl TryFrom<&Pmt> for isize {
315    type Error = PmtConversionError;
316
317    fn try_from(value: &Pmt) -> Result<isize, Self::Error> {
318        match value {
319            Pmt::Isize(f) => Ok(*f),
320            _ => Err(PmtConversionError),
321        }
322    }
323}
324
325impl TryFrom<Pmt> for isize {
326    type Error = PmtConversionError;
327
328    fn try_from(value: Pmt) -> Result<isize, Self::Error> {
329        (&value).try_into()
330    }
331}
332
333impl TryFrom<&Pmt> for u64 {
334    type Error = PmtConversionError;
335
336    fn try_from(value: &Pmt) -> Result<u64, Self::Error> {
337        match value {
338            Pmt::U32(v) => Ok(*v as u64),
339            Pmt::U64(v) => Ok(*v),
340            Pmt::Usize(v) => Ok(*v as u64),
341            _ => Err(PmtConversionError),
342        }
343    }
344}
345
346impl TryFrom<Pmt> for u64 {
347    type Error = PmtConversionError;
348
349    fn try_from(value: Pmt) -> Result<u64, Self::Error> {
350        (&value).try_into()
351    }
352}
353
354impl TryFrom<&Pmt> for bool {
355    type Error = PmtConversionError;
356
357    fn try_from(value: &Pmt) -> Result<bool, Self::Error> {
358        match value {
359            Pmt::Bool(b) => Ok(*b),
360            _ => Err(PmtConversionError),
361        }
362    }
363}
364
365impl TryFrom<Pmt> for bool {
366    type Error = PmtConversionError;
367
368    fn try_from(value: Pmt) -> Result<bool, Self::Error> {
369        (&value).try_into()
370    }
371}
372
373impl TryFrom<Pmt> for Vec<f32> {
374    type Error = PmtConversionError;
375
376    fn try_from(value: Pmt) -> Result<Vec<f32>, Self::Error> {
377        match value {
378            Pmt::VecF32(v) => Ok(v),
379            _ => Err(PmtConversionError),
380        }
381    }
382}
383
384impl TryFrom<Pmt> for Vec<Complex32> {
385    type Error = PmtConversionError;
386
387    fn try_from(value: Pmt) -> Result<Vec<Complex32>, Self::Error> {
388        match value {
389            Pmt::VecCF32(v) => Ok(v),
390            _ => Err(PmtConversionError),
391        }
392    }
393}
394
395impl TryFrom<Pmt> for Vec<u64> {
396    type Error = PmtConversionError;
397
398    fn try_from(value: Pmt) -> Result<Vec<u64>, Self::Error> {
399        match value {
400            Pmt::VecU64(v) => Ok(v),
401            _ => Err(PmtConversionError),
402        }
403    }
404}
405
406impl From<()> for Pmt {
407    fn from(_: ()) -> Self {
408        Pmt::Null
409    }
410}
411
412impl From<bool> for Pmt {
413    fn from(b: bool) -> Self {
414        Pmt::Bool(b)
415    }
416}
417
418impl From<f32> for Pmt {
419    fn from(f: f32) -> Self {
420        Pmt::F32(f)
421    }
422}
423
424impl From<f64> for Pmt {
425    fn from(f: f64) -> Self {
426        Pmt::F64(f)
427    }
428}
429
430impl From<u32> for Pmt {
431    fn from(f: u32) -> Self {
432        Pmt::U32(f)
433    }
434}
435
436impl From<u64> for Pmt {
437    fn from(f: u64) -> Self {
438        Pmt::U64(f)
439    }
440}
441
442impl From<usize> for Pmt {
443    fn from(f: usize) -> Self {
444        Pmt::Usize(f)
445    }
446}
447
448impl From<isize> for Pmt {
449    fn from(f: isize) -> Self {
450        Pmt::Isize(f)
451    }
452}
453
454impl From<Vec<f32>> for Pmt {
455    fn from(v: Vec<f32>) -> Self {
456        Pmt::VecF32(v)
457    }
458}
459
460impl From<Vec<u64>> for Pmt {
461    fn from(v: Vec<u64>) -> Self {
462        Pmt::VecU64(v)
463    }
464}
465
466impl From<Vec<Complex32>> for Pmt {
467    fn from(v: Vec<Complex32>) -> Self {
468        Pmt::VecCF32(v)
469    }
470}
471
472/// PMT types that do not wrap values.
473///
474/// Useful for bindings to other languages that do not support Rust's broad enum features.
475#[non_exhaustive]
476#[derive(Debug, Clone, PartialEq, Eq, Hash)]
477pub enum PmtKind {
478    /// Ok
479    Ok,
480    /// Invalid value
481    InvalidValue,
482    /// Null
483    Null,
484    /// String
485    String,
486    /// Bool
487    Bool,
488    /// Usize
489    Usize,
490    /// Isize
491    Isize,
492    /// U32
493    U32,
494    /// U64
495    U64,
496    /// F32
497    F32,
498    /// F64
499    F64,
500    /// VecCF32
501    VecCF32,
502    /// VecF32
503    VecF32,
504    /// VecU64
505    VecU64,
506    /// Blob
507    Blob,
508    /// Vec Pmt
509    VecPmt,
510    /// Finished
511    Finished,
512    /// Map String -> Pmt
513    MapStrPmt,
514    /// Any
515    Any,
516}
517
518impl From<Pmt> for PmtKind {
519    fn from(value: Pmt) -> Self {
520        value.kind()
521    }
522}
523
524impl From<&Pmt> for PmtKind {
525    fn from(value: &Pmt) -> Self {
526        value.kind()
527    }
528}
529
530impl fmt::Display for PmtKind {
531    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
532        match self {
533            PmtKind::Ok => write!(f, "Ok"),
534            PmtKind::InvalidValue => write!(f, "InvalidValue"),
535            PmtKind::Null => write!(f, "Null"),
536            PmtKind::String => write!(f, "String"),
537            PmtKind::Bool => write!(f, "Bool"),
538            PmtKind::Usize => write!(f, "Usize"),
539            PmtKind::Isize => write!(f, "isize"),
540            PmtKind::U32 => write!(f, "U32"),
541            PmtKind::U64 => write!(f, "U64"),
542            PmtKind::F32 => write!(f, "F32"),
543            PmtKind::F64 => write!(f, "F64"),
544            PmtKind::VecCF32 => write!(f, "VecCF32"),
545            PmtKind::VecF32 => write!(f, "VecF32"),
546            PmtKind::VecU64 => write!(f, "VecU64"),
547            PmtKind::Blob => write!(f, "Blob"),
548            PmtKind::VecPmt => write!(f, "VecPmt"),
549            PmtKind::Finished => write!(f, "Finished"),
550            PmtKind::MapStrPmt => write!(f, "MapStrPmt"),
551            PmtKind::Any => write!(f, "Any"),
552        }
553    }
554}
555
556impl std::str::FromStr for PmtKind {
557    type Err = PmtConversionError;
558
559    fn from_str(s: &str) -> Result<Self, Self::Err> {
560        match s {
561            "Ok" => return Ok(PmtKind::Ok),
562            "InvalidValue" => return Ok(PmtKind::InvalidValue),
563            "Null" => return Ok(PmtKind::Null),
564            "String" => return Ok(PmtKind::String),
565            "Bool" => return Ok(PmtKind::Bool),
566            "Usize" => return Ok(PmtKind::Usize),
567            "Isize" => return Ok(PmtKind::Isize),
568            "U32" => return Ok(PmtKind::U32),
569            "U64" => return Ok(PmtKind::U64),
570            "F32" => return Ok(PmtKind::F32),
571            "F64" => return Ok(PmtKind::F64),
572            "VecF32" => return Ok(PmtKind::VecF32),
573            "VecU64" => return Ok(PmtKind::VecU64),
574            "Blob" => return Ok(PmtKind::Blob),
575            "VecPmt" => return Ok(PmtKind::VecPmt),
576            "Finished" => return Ok(PmtKind::Finished),
577            "MapStrPmt" => return Ok(PmtKind::MapStrPmt),
578            "Any" => return Ok(PmtKind::Any),
579            _ => (),
580        }
581        Err(PmtConversionError)
582    }
583}
584
585#[cfg(test)]
586mod test {
587    use super::*;
588
589    #[test]
590    fn pmt() {
591        let p = Pmt::Null;
592        assert_eq!(p.to_string(), "Null");
593        let p = Pmt::String("foo".to_string());
594        assert_eq!(p.to_string(), "foo");
595    }
596
597    #[test]
598    fn pmt_parse_json() {
599        let s = "{ \"U32\": 123 }";
600        assert_eq!(s.parse::<Pmt>(), Ok(Pmt::U32(123)));
601        let s = "{ \"Bool\": true }";
602        assert_eq!(s.parse::<Pmt>(), Ok(Pmt::Bool(true)));
603        let s = "Bool: true";
604        assert_eq!(s.parse::<Pmt>(), Ok(Pmt::Bool(true)));
605        let s = "U32: 123";
606        assert_eq!(s.parse::<Pmt>(), Ok(Pmt::U32(123)));
607        let s = "F64: 123";
608        assert_eq!(s.parse::<Pmt>(), Ok(Pmt::F64(123.0)));
609        let s = "Blob: [1,2,3]";
610        assert_eq!(s.parse::<Pmt>(), Ok(Pmt::Blob(vec![1, 2, 3])));
611    }
612
613    #[test]
614    fn pmt_serde() {
615        let p = Pmt::Null;
616        let mut s = flexbuffers::FlexbufferSerializer::new();
617        p.serialize(&mut s).unwrap();
618
619        let r = flexbuffers::Reader::get_root(s.view()).unwrap();
620        let p2 = Pmt::deserialize(r).unwrap();
621
622        assert_eq!(p, p2);
623    }
624
625    #[allow(clippy::many_single_char_names)]
626    #[test]
627    fn pmt_eq() {
628        let a = Pmt::Null;
629        let b = Pmt::U32(123);
630        assert_ne!(a, b);
631
632        let c = Pmt::Null;
633        let d = Pmt::U32(12);
634        let e = Pmt::U32(123);
635        assert_eq!(a, c);
636        assert_eq!(b, e);
637        assert_ne!(b, d);
638
639        let f1 = Pmt::F32(0.1);
640        let f2 = Pmt::F32(0.1);
641        let f3 = Pmt::F32(0.2);
642        assert_eq!(f1, f2);
643        assert_ne!(f1, f3);
644
645        let fv1 = Pmt::VecF32(vec![1.0, 2.0, 3.0]);
646        let fv2 = Pmt::VecF32(vec![1.0, 2.0, 3.0]);
647        assert_eq!(fv1, fv2);
648
649        let cfv1 = Pmt::VecCF32(vec![Complex32::new(1.0, 2.0), Complex32::new(3.0, 4.0)]);
650        let cfv2 = Pmt::VecCF32(vec![Complex32::new(1.0, 2.0), Complex32::new(3.0, 4.0)]);
651        assert_eq!(cfv1, cfv2);
652    }
653
654    #[test]
655    fn vec_pmt() {
656        let vpmt = Pmt::VecPmt(vec![Pmt::U32(1), Pmt::U32(2)]);
657
658        if let Pmt::VecPmt(v) = vpmt {
659            assert_eq!(v[0], Pmt::U32(1));
660            assert_eq!(v[1], Pmt::U32(2));
661        } else {
662            panic!("Not a Pmt::VecPmt");
663        }
664    }
665
666    #[test]
667    fn map_str_pmt() {
668        let u32val = 42;
669        let f64val = 6.02214076e23;
670
671        let msp = Pmt::MapStrPmt(HashMap::from([
672            ("str".to_owned(), Pmt::String("a string".to_owned())),
673            (
674                "submap".to_owned(),
675                Pmt::MapStrPmt(HashMap::from([
676                    ("U32".to_owned(), Pmt::U32(u32val)),
677                    ("F64".to_owned(), Pmt::F64(f64val)),
678                ])),
679            ),
680        ]));
681
682        if let Pmt::MapStrPmt(m) = msp {
683            if let Some(Pmt::MapStrPmt(sm)) = m.get("submap") {
684                assert_eq!(sm.get("U32"), Some(&Pmt::U32(u32val)));
685                assert_eq!(sm.get("F64"), Some(&Pmt::F64(f64val)));
686            } else {
687                panic!("Could not get submap");
688            }
689        } else {
690            panic!("Not a Pmt::MapStrPmt");
691        }
692    }
693
694    #[test]
695    fn from_into() {
696        let e = 42usize;
697        let p = Pmt::from(e);
698        assert_eq!(p, Pmt::Usize(e));
699        assert_eq!((&p).try_into(), Ok(e));
700
701        let e = 42isize;
702        let p = Pmt::from(e);
703        assert_eq!(p, Pmt::Isize(e));
704        assert_eq!((&p).try_into(), Ok(e));
705
706        let e = 42u32;
707        let p = Pmt::from(e);
708        assert_eq!(p, Pmt::U32(e));
709        // Lossy conversion unsupported
710        // assert_eq!(p.try_into(), Ok(e));
711
712        let e = 42u64;
713        let p = Pmt::from(e);
714        assert_eq!(p, Pmt::U64(e));
715        assert_eq!((&p).try_into(), Ok(e));
716
717        let e = 42f64;
718        let p = Pmt::from(e);
719        assert_eq!(p, Pmt::F64(e));
720        assert_eq!(p.try_into(), Ok(e));
721
722        let e = 42f32;
723        let p = Pmt::from(e);
724        assert_eq!(p, Pmt::F32(e));
725        // Lossy conversion unsupported
726        //assert_eq!(p.try_into(), Ok(e));
727
728        let e = true;
729        let p = Pmt::from(e);
730        assert_eq!(p, Pmt::Bool(e));
731        assert_eq!((&p).try_into(), Ok(e));
732
733        let e = vec![1.0, 2.0, 3.0];
734        let p = Pmt::from(e.clone());
735        assert_eq!(p, Pmt::VecF32(e.clone()));
736        assert_eq!(p.try_into(), Ok(e));
737
738        let e = vec![1, 2, 3];
739        let p = Pmt::from(e.clone());
740        assert_eq!(p, Pmt::VecU64(e.clone()));
741        assert_eq!(p.try_into(), Ok(e));
742
743        let e = vec![Complex32::new(1.0, 2.0), Complex32::new(3.0, 4.0)];
744        let p = Pmt::from(e.clone());
745        assert_eq!(p, Pmt::VecCF32(e.clone()));
746        assert_eq!(p.try_into(), Ok(e));
747    }
748
749    #[test]
750    fn pmt_kind() {
751        let p = Pmt::U32(42);
752        assert_eq!(PmtKind::U32, p.kind());
753        assert_eq!(PmtKind::U32, p.into());
754
755        let p = Pmt::F64(42.0);
756        assert_eq!(PmtKind::F64, p.kind());
757        assert_eq!(PmtKind::F64, p.into());
758
759        let p = Pmt::VecF32(vec![]);
760        assert_eq!(PmtKind::VecF32, p.kind());
761        assert_eq!(PmtKind::VecF32, p.into());
762
763        let p = Pmt::VecU64(vec![]);
764        assert_eq!(PmtKind::VecU64, p.kind());
765        assert_eq!(PmtKind::VecU64, (&p).into());
766
767        let p = Pmt::VecCF32(vec![]);
768        assert_eq!(PmtKind::VecCF32, p.kind());
769        assert_eq!(PmtKind::VecCF32, (&p).into());
770    }
771
772    #[test]
773    fn take_any() {
774        let p = Pmt::Any(Box::new(vec![1u8]));
775
776        let Pmt::Any(p_any) = p else { unreachable!() };
777        assert!(p_any.is::<Vec<u8>>());
778
779        let v = p_any.take::<Vec<u8>>().unwrap();
780        assert_eq!(v[0], 1u8)
781    }
782}