1use std::fmt::Display;
2use std::fmt::Error;
3
4pub trait Identifier: Display {
5 fn value(&self) -> &str;
6}
7pub trait AsIdentifier<ById: Identifier> {
10 fn as_id(&self) -> &ById;
11}
12
13impl<T> AsIdentifier<T> for T
14where
15 T: Identifier,
16{
17 fn as_id(&self) -> &T {
18 self
19 }
20}
21
22impl<T> AsIdentifier<T> for &T
23where
24 T: Identifier,
25{
26 fn as_id(&self) -> &T {
27 self
28 }
29}
30
31macro_rules! identifer {
32 ($name:ident) => {
33 #[derive(serde::Serialize, serde::Deserialize, Debug, Eq, PartialEq, Hash, Clone)]
34 #[serde(transparent)]
35 pub struct $name(String);
36
37 impl Identifier for $name {
38 fn value(&self) -> &str {
39 &self.0
40 }
41 }
42
43 impl std::fmt::Display for $name {
44 fn fmt(
45 &self,
46 f: &mut std::fmt::Formatter<'_>,
47 ) -> std::fmt::Result {
48 self.0.fmt(f)
49 }
50 }
51
52 impl std::str::FromStr for $name {
53 type Err = Error;
54
55 fn from_str(s: &str) -> Result<Self, Self::Err> {
56 Ok($name(s.to_string()))
57 }
58 }
59 };
60}
61
62identifer!(DatabaseId);
63identifer!(PageId);
64identifer!(BlockId);
65identifer!(UserId);
66identifer!(PropertyId);
67
68impl From<PageId> for BlockId {
69 fn from(page_id: PageId) -> Self {
70 BlockId(page_id.0)
71 }
72}