1use std::marker::PhantomData;
2use std::sync::Arc;
3
4#[derive(Debug)]
11pub struct Place<T: 'static> {
12 name: Arc<str>,
13 _phantom: PhantomData<fn() -> T>,
14}
15
16impl<T: 'static> Place<T> {
17 pub fn new(name: impl Into<Arc<str>>) -> Self {
19 Self {
20 name: name.into(),
21 _phantom: PhantomData,
22 }
23 }
24
25 pub fn name(&self) -> &str {
27 &self.name
28 }
29
30 pub fn name_arc(&self) -> &Arc<str> {
32 &self.name
33 }
34
35 pub fn as_ref(&self) -> PlaceRef {
37 PlaceRef(Arc::clone(&self.name))
38 }
39}
40
41impl<T: 'static> Clone for Place<T> {
42 fn clone(&self) -> Self {
43 Self {
44 name: Arc::clone(&self.name),
45 _phantom: PhantomData,
46 }
47 }
48}
49
50impl<T: 'static> PartialEq for Place<T> {
51 fn eq(&self, other: &Self) -> bool {
52 self.name == other.name
53 }
54}
55
56impl<T: 'static> Eq for Place<T> {}
57
58impl<T: 'static> std::hash::Hash for Place<T> {
59 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
60 self.name.hash(state);
61 }
62}
63
64#[derive(Debug, Clone)]
67pub struct EnvironmentPlace<T: 'static> {
68 place: Place<T>,
69}
70
71impl<T: 'static> EnvironmentPlace<T> {
72 pub fn new(name: impl Into<Arc<str>>) -> Self {
74 Self {
75 place: Place::new(name),
76 }
77 }
78
79 pub fn place(&self) -> &Place<T> {
81 &self.place
82 }
83
84 pub fn name(&self) -> &str {
86 self.place.name()
87 }
88}
89
90#[derive(Debug, Clone, PartialEq, Eq, Hash)]
94pub struct PlaceRef(pub(crate) Arc<str>);
95
96impl PlaceRef {
97 pub fn new(name: impl Into<Arc<str>>) -> Self {
99 Self(name.into())
100 }
101
102 pub fn name(&self) -> &str {
104 &self.0
105 }
106
107 pub fn name_arc(&self) -> &Arc<str> {
109 &self.0
110 }
111}
112
113impl<T: 'static> From<&Place<T>> for PlaceRef {
114 fn from(place: &Place<T>) -> Self {
115 place.as_ref()
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122
123 #[test]
124 fn place_equality_by_name() {
125 let p1: Place<i32> = Place::new("test");
126 let p2: Place<i32> = Place::new("test");
127 assert_eq!(p1, p2);
128 }
129
130 #[test]
131 fn place_inequality() {
132 let p1: Place<i32> = Place::new("a");
133 let p2: Place<i32> = Place::new("b");
134 assert_ne!(p1, p2);
135 }
136
137 #[test]
138 fn place_clone_is_cheap() {
139 let p: Place<i32> = Place::new("test");
140 let p2 = p.clone();
141 assert!(Arc::ptr_eq(p.name_arc(), p2.name_arc()));
142 }
143
144 #[test]
145 fn place_ref_from_place() {
146 let p: Place<i32> = Place::new("test");
147 let r = PlaceRef::from(&p);
148 assert_eq!(r.name(), "test");
149 }
150
151 #[test]
152 fn environment_place() {
153 let ep = EnvironmentPlace::<String>::new("events");
154 assert_eq!(ep.name(), "events");
155 assert_eq!(ep.place().name(), "events");
156 }
157}