Skip to main content

mzdata_param/
units.rs

1use std::fmt::Display;
2
3use crate::{CURIE, ControlledVocabulary, Param};
4
5/// Easily define all units. See the usage for more details. The accession and name both have to be
6/// included in `&'static str` and `byte slice` to allow for constant time matching.
7macro_rules! units {
8    [$($unit:ident, $accession:literal, $baccession:literal, $name:literal, $bname:literal, $cv:ident, $id:literal);*;] => {
9        /// Units that a term's value might have
10        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
11        #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12        pub enum Unit {
13            Unknown,
14            $($unit,)*
15        }
16
17        impl Unit {
18            pub const fn for_param(&self) -> (&'static str, &'static str) {
19                match self {
20                    $(Self::$unit => ($accession, $name),)*
21                    Self::Unknown => ("","")
22                }
23            }
24
25            pub const fn from_name(name: &str) -> Unit {
26                match name.as_bytes() {
27                    $($bname => Self::$unit,)*
28                    _ => Self::Unknown
29                }
30            }
31
32            pub const fn from_accession(acc: &str) -> Unit {
33                match acc.as_bytes() {
34                    $($baccession => Self::$unit,)*
35                    _ => Self::Unknown
36                }
37            }
38
39            pub const fn from_curie(acc: &CURIE) -> Unit {
40                match acc {
41                    $(CURIE {
42                        controlled_vocabulary: ControlledVocabulary::$cv,
43                        accession: $id,
44                    } => Self::$unit,)*
45                    _ => Self::Unknown
46                }
47            }
48
49            pub const fn to_curie(&self) -> Option<CURIE> {
50                match self {
51                    $(Self::$unit => Some(CURIE {
52                        controlled_vocabulary: ControlledVocabulary::$cv,
53                        accession: $id,
54                    }),)*
55                    Self::Unknown => None
56                }
57            }
58
59            pub const fn from_param(param: &Param) -> Unit {
60                param.unit
61            }
62
63            pub const fn is_unknown(&self) -> bool {
64                matches!(self, Self::Unknown)
65            }
66        }
67    };
68}
69
70units![
71    AbsorbanceUnit, "UO:0000269", b"UO:0000269", "absorbance unit", b"absorbance unit", UO, 269;
72    Celsius, "UO:0000027", b"UO:0000027", "degree Celsius", b"degree Celsius", UO, 27;
73    CountsPerSecond, "MS:1000814", b"MS:1000814", "counts per second", b"counts per second", MS, 1000814;
74    DetectorCounts, "MS:1000131", b"MS:1000131", "number of detector counts", b"number of detector counts", MS, 1000131;
75    Dimensionless, "UO:0000186", b"UO:0000186", "dimensionless unit", b"dimensionless unit", UO, 186;
76    Electronvolt, "UO:0000266", b"UO:0000266", "electronvolt", b"electronvolt", UO, 266;
77    Kelvin, "UO:0000012", b"UO:0000012", "kelvin", b"kelvin", UO, 12;
78    Mass, "UO:000221", b"UO:000221", "dalton", b"dalton", UO, 221;
79    MicrolitersPerMinute, "UO:0000271", b"UO:0000271", "microliters per minute", b"microliters per minute", UO, 271;
80    Millisecond, "UO:0000028", b"UO:0000028", "millisecond", b"millisecond", UO, 28;
81    Minute, "UO:0000031", b"UO:0000031", "minute", b"minute", UO, 31;
82    MZ, "MS:1000040", b"MS:1000040", "m/z", b"m/z", MS, 1000040;
83    Nanometer, "UO:0000018", b"UO:0000018", "nanometer", b"nanometer", UO, 18;
84    Micrometer, "UO:0000017", b"UO:0000017", "micrometer", b"micrometer", UO, 17;
85    Millimeter, "UO:0000016", b"UO:0000016", "millimeter", b"millimeter", UO, 16;
86    Centimeter, "UO:0000015", b"UO:0000015", "centimeter", b"centimeter", UO, 15;
87    PartsPerMillion, "UO:0000169", b"UO:0000169", "parts per million ", b"parts per million ", UO, 169;
88    Pascal, "UO:0000110", b"UO:0000110", "pascal", b"pascal", UO, 110;
89    Percent, "UO:0000187", b"UO:0000187", "percent", b"percent", UO, 187;
90    PercentBasePeak, "MS:1000132", b"MS:1000132", "percent of base peak", b"percent of base peak", MS, 1000132;
91    PercentBasePeakTimes100, "MS:1000905", b"MS:1000905", "percent of base peak times 100", b"percent of base peak times 100", MS, 1000905;
92    Psi, "UO:0010052", b"UO:0010052", "pounds per square inch", b"pounds per square inch", UO, 10052;
93    Second, "UO:0000010", b"UO:0000010", "second", b"second", UO, 10;
94    Volt, "UO:0000218", b"UO:0000218", "volt", b"volt", UO, 218;
95    VoltSecondPerSquareCentimeter, "MS:1002814", b"MS:1002814", "volt-second per square centimeter", b"volt-second per square centimeter", MS, 1002814;
96    Hertz, "UO:000106", b"UO:000106", "hertz", b"hertz", UO, 106;
97    Liter, "UO:0000099", b"UO:0000099", "liter", b"liter", UO, 99;
98    Milliliter, "UO:0000098", b"UO:0000098", "milliliter", b"milliliter", UO, 98;
99    Microliter, "UO:0000101", b"UO:0000101", "microliter", b"microliter", UO, 101;
100];
101
102impl Default for Unit {
103    fn default() -> Self {
104        Self::Unknown
105    }
106}
107
108impl Display for Unit {
109    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
110        f.write_str(format!("{:?}", self).as_str())
111    }
112}