1use std::{
2 any::{Any, TypeId},
3 collections::HashMap,
4 ops::{Deref, DerefMut},
5 str::FromStr,
6};
7
8use faststr::FastStr;
9
10#[derive(Default, Debug)]
11pub struct TypeMap(HashMap<TypeId, Box<dyn Any + Sync + Send>>);
12
13impl TypeMap {
14 pub fn insert<T: 'static + Sync + Send>(&mut self, v: T) {
15 self.0.insert(TypeId::of::<T>(), Box::new(v));
16 }
17
18 pub fn get<T: 'static>(&self) -> Option<&T> {
19 self.0
20 .get(&TypeId::of::<T>())
21 .map(|v| v.downcast_ref().unwrap())
22 }
23
24 pub fn is_empty(&self) -> bool {
25 self.0.is_empty()
26 }
27
28 pub fn len(&self) -> usize {
29 self.0.len()
30 }
31
32 pub fn contains<T: 'static>(&self) -> bool {
33 self.0.contains_key(&TypeId::of::<T>())
34 }
35
36 pub fn remove<T: 'static>(&mut self) {
37 self.0.remove(&TypeId::of::<T>());
38 }
39}
40
41#[derive(Default, Debug)]
42pub struct Tags(TypeMap);
43
44impl Deref for Tags {
45 type Target = TypeMap;
46
47 fn deref(&self) -> &Self::Target {
48 &self.0
49 }
50}
51
52impl DerefMut for Tags {
53 fn deref_mut(&mut self) -> &mut Self::Target {
54 &mut self.0
55 }
56}
57
58#[derive(Clone)]
59pub struct Construct(pub FastStr);
60
61pub trait Annotation: FromStr {
62 const KEY: &'static str;
63}
64
65impl FromStr for Construct {
66 type Err = std::convert::Infallible;
67
68 fn from_str(s: &str) -> Result<Self, Self::Err> {
69 Ok(Self(FastStr::new(s)))
70 }
71}
72
73impl Annotation for Construct {
74 const KEY: &'static str = "default";
75}
76
77#[derive(Clone)]
78pub struct Editable(pub bool);
79
80impl FromStr for Editable {
81 type Err = std::convert::Infallible;
82
83 fn from_str(s: &str) -> Result<Self, Self::Err> {
84 Ok(Self(s == "true"))
85 }
86}
87
88impl Annotation for Editable {
89 const KEY: &'static str = "editable";
90}