hass_entity_state/
attributes.rs

1mod serde;
2
3use crate::EntityState;
4use std::{
5  borrow::{Borrow, Cow},
6  collections::{btree_map, BTreeMap},
7  fmt,
8  marker::PhantomData,
9};
10
11pub trait AttributeValue<'a>: Eq + Borrow<str> + ::serde::Deserialize<'a> {
12  fn from_cow(value: Cow<'a, str>) -> Self;
13}
14pub trait AttributeKey<'a>: Ord + AttributeValue<'a> {}
15
16impl<'a> AttributeValue<'a> for String {
17  fn from_cow(value: Cow<'a, str>) -> Self {
18    value.into_owned()
19  }
20}
21
22impl<'a> AttributeValue<'a> for Cow<'a, str> {
23  fn from_cow(value: Cow<'a, str>) -> Self {
24    value
25  }
26}
27
28impl<'a> AttributeKey<'a> for String {}
29impl<'a> AttributeKey<'a> for Cow<'a, str> {}
30
31pub struct Attributes<'a, K, V, E: ?Sized>(BTreeMap<K, V>, PhantomData<fn() -> &'a E>)
32where
33  K: AttributeKey<'a>,
34  V: AttributeValue<'a>,
35  E: EntityState<'a, K, V>;
36
37impl<'a, K, V, E> Default for Attributes<'a, K, V, E>
38where
39  K: AttributeKey<'a>,
40  V: AttributeValue<'a>,
41  E: EntityState<'a, K, V>,
42{
43  fn default() -> Self {
44    Self(BTreeMap::default(), PhantomData)
45  }
46}
47
48impl<'a, K, V, E> fmt::Debug for Attributes<'a, K, V, E>
49where
50  K: AttributeKey<'a>,
51  V: AttributeValue<'a>,
52  E: EntityState<'a, K, V>,
53{
54  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55    f.debug_map()
56      .entries(self.0.iter().map(|(k, v)| (k.borrow(), v.borrow())))
57      .finish()
58  }
59}
60
61impl<'a, K, V, E> PartialEq for Attributes<'a, K, V, E>
62where
63  K: AttributeKey<'a>,
64  V: AttributeValue<'a>,
65  E: EntityState<'a, K, V>,
66{
67  fn eq(&self, other: &Self) -> bool {
68    self.0.eq(&other.0)
69  }
70}
71
72impl<'a, K, V, E> Attributes<'a, K, V, E>
73where
74  K: AttributeKey<'a>,
75  V: AttributeValue<'a>,
76  E: EntityState<'a, K, V>,
77{
78  pub fn get(&self, key: &str) -> Option<&str> {
79    self.get_inner(key).map(|v| (*v).borrow())
80  }
81
82  pub fn get_inner(&self, key: &str) -> Option<&V> {
83    self.0.get(key)
84  }
85
86  pub fn insert(&mut self, key: K, value: V) -> Option<V> {
87    self.0.insert(key, value)
88  }
89
90  pub fn remove(&mut self, key: &str) -> Option<V> {
91    self.0.remove(key)
92  }
93}
94
95pub struct Entry<'a, 'b, K, V>
96where
97  K: AttributeKey<'a>,
98  V: AttributeValue<'a>,
99{
100  inner: btree_map::Entry<'b, K, V>,
101  marker: PhantomData<&'a ()>,
102}
103
104impl<'a, 'b, K, V> Entry<'a, 'b, K, V>
105where
106  K: AttributeKey<'a>,
107  V: AttributeValue<'a>,
108{
109  pub fn key(&self) -> &str {
110    self.key_inner().borrow()
111  }
112
113  pub fn key_inner(&self) -> &K {
114    self.inner.key()
115  }
116
117  pub fn or_insert(self, default: V) -> &'b mut V {
118    self.inner.or_insert(default)
119  }
120
121  pub fn or_insert_with(self, default: impl FnOnce() -> V) -> &'b mut V {
122    self.inner.or_insert_with(default)
123  }
124
125  pub fn and_modify(self, f: impl FnOnce(&mut V)) -> Self {
126    Entry {
127      inner: self.inner.and_modify(f),
128      marker: PhantomData,
129    }
130  }
131}
132
133impl<'a, K, V, E> Attributes<'a, K, V, E>
134where
135  K: AttributeKey<'a>,
136  V: AttributeValue<'a>,
137  E: EntityState<'a, K, V>,
138{
139  pub fn entry<'b>(&'b mut self, key: K) -> Entry<'a, 'b, K, V> {
140    Entry {
141      inner: self.0.entry(key),
142      marker: PhantomData,
143    }
144  }
145}