1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//! This is an auto-generated wrapper around the `om2:Unit` class, with a few
//! supporting structs/enums/utils.
//!
//! The idea here is to map Unit into a big (de)serializable rust enum, so you
//! don't need to know the label/symbol up front but can just grab it from the
//! Unit enum:
//!
//! ```rust
//! use om2::Unit;
//!
//! let wh = Unit::WattHour;
//! assert_eq!(wh.symbol(), Some("W h".to_string()));
//! assert_eq!(wh.label(), Some("watt hour".to_string()));
//! ```
//!
//! Note that the `symbol()` and `label()` methods return Option because not all
//! the enum values have those fields defined int he schema.
//!
//! This crate also exports `om2:Measure`, useful for holding full measurements.
//! It also has getters by default, with the option to include setters as well:
//!
//! ```rust
//! use om2::{Unit, Measure, NumericUnion};
//! let measure = Measure::new(7.3 as f64, Unit::Hour);
//! assert_eq!(measure.has_unit(), &Unit::Hour);
//! assert_eq!(measure.has_numerical_value(), &NumericUnion::Double(7.3));
//! ```
//!
//! Note that none of the available RDF/XML rust libs were able to parse the om2
//! RDF schema, so this library requires conversion to .ttl first (this is done
//! via the `make schema` command, which uses the `rapper` command line util
//! under the hood).
//!
//! Features:
//!
//! - `getset_setters` - implements setters on the generated structs so they can
//! be mutated in-place via setter methods
//! - `getset_getmut` - implements mutable getters on the generated structs so
//! they can be mutated in-place via &mut getters
//!
//! Note that *all* features are enabled when building the docs to give a sense
//! of the library's full abilities.

use getset::Getters;
#[cfg(feature = "getset_setters")]
use getset::Setters;
#[cfg(feature = "getset_getmut")]
use getset::MutGetters;
#[cfg(feature = "with_serde")]
use serde_derive::{Serialize, Deserialize};

mod gen;
mod dtype;

pub use gen::*;
pub use dtype::*;

/// A numeric value with its unit of measure.
///
/// ID: http://www.ontology-of-units-of-measure.org/resource/om-2/Measure
#[derive(Debug, PartialEq, Clone, Getters)]
#[cfg_attr(feature = "getset_setters", derive(Setters))]
#[cfg_attr(feature = "getset_getmut", derive(MutGetters))]
#[cfg_attr(feature = "with_serde", derive(Serialize, Deserialize))]
#[getset(get = "pub", set = "pub", get_mut = "pub")]
pub struct Measure {
    pub has_numerical_value: dtype::NumericUnion,
    pub has_unit: Unit,
}

impl Measure {
    pub fn new<T: Into<NumericUnion>>(value: T, unit: Unit) -> Self {
        Self {
            has_numerical_value: value.into(),
            has_unit: unit,
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn can_build() {
        let measure = Measure::new(42.0 as f64, Unit::WattHour);
        assert_eq!(measure.has_numerical_value(), &NumericUnion::Double(42.0));
        assert_eq!(measure.has_unit(), &Unit::WattHour);
    }
}