1use core::fmt;
9
10use crate::thing::{FeatureId, PropertyId, ThingId};
11
12#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18pub struct PropertyPath {
19 #[cfg_attr(feature = "serde", serde(rename = "thingId"))]
21 pub thing: ThingId,
22 #[cfg_attr(feature = "serde", serde(rename = "featureId"))]
24 pub feature: FeatureId,
25 #[cfg_attr(feature = "serde", serde(rename = "propertyId"))]
27 pub property: PropertyId,
28}
29
30impl PropertyPath {
31 pub fn new(thing: ThingId, feature: FeatureId, property: PropertyId) -> Self {
33 Self {
34 thing,
35 feature,
36 property,
37 }
38 }
39}
40
41impl fmt::Display for PropertyPath {
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 write!(
46 f,
47 "{}/{}/{}",
48 self.thing.as_str(),
49 self.feature.as_str(),
50 self.property.as_str()
51 )
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn display_canonical() {
61 let p = PropertyPath::new(
62 ThingId::new("acme:pump-7"),
63 FeatureId::new("temperature"),
64 PropertyId::new("value"),
65 );
66 assert_eq!(p.to_string(), "acme:pump-7/temperature/value");
67 }
68}