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}