Skip to main content

tasktree/identity/
traits.rs

1use std::fmt::{
2    Display,
3    Formatter,
4};
5use std::str::FromStr;
6
7use serde::{
8    Deserialize,
9    Serialize,
10};
11
12use super::{
13    TaskId,
14    TaskIdentityError,
15    TaskNodeId,
16    TaskTreeId,
17};
18use crate::scheme::UrnScheme;
19
20macro_rules! impl_string_traits {
21    ($type:ty, $parse:path) => {
22        impl Display for $type {
23            fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
24                formatter.write_str(self.as_str())
25            }
26        }
27
28        impl FromStr for $type {
29            type Err = TaskIdentityError;
30
31            fn from_str(raw: &str) -> Result<Self, Self::Err> {
32                $parse(raw)
33            }
34        }
35
36        impl AsRef<str> for $type {
37            fn as_ref(&self) -> &str {
38                self.as_str()
39            }
40        }
41
42        impl Serialize for $type {
43            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
44            where
45                S: serde::Serializer,
46            {
47                serializer.serialize_str(self.as_str())
48            }
49        }
50
51        impl<'de> Deserialize<'de> for $type {
52            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
53            where
54                D: serde::Deserializer<'de>,
55            {
56                let raw = String::deserialize(deserializer)?;
57                $parse(&raw).map_err(serde::de::Error::custom)
58            }
59        }
60    };
61}
62
63macro_rules! impl_scheme_string_traits {
64    ($type:ident, $parse:path) => {
65        impl<S: UrnScheme> Display for $type<S> {
66            fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
67                formatter.write_str(self.as_str())
68            }
69        }
70
71        impl<S: UrnScheme> FromStr for $type<S> {
72            type Err = TaskIdentityError;
73
74            fn from_str(raw: &str) -> Result<Self, Self::Err> {
75                $parse(raw)
76            }
77        }
78
79        impl<S: UrnScheme> AsRef<str> for $type<S> {
80            fn as_ref(&self) -> &str {
81                self.as_str()
82            }
83        }
84
85        impl<S: UrnScheme> Serialize for $type<S> {
86            fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
87            where
88                Ser: serde::Serializer,
89            {
90                serializer.serialize_str(self.as_str())
91            }
92        }
93
94        impl<'de, S: UrnScheme> Deserialize<'de> for $type<S> {
95            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
96            where
97                D: serde::Deserializer<'de>,
98            {
99                let raw = String::deserialize(deserializer)?;
100                $parse(&raw).map_err(serde::de::Error::custom)
101            }
102        }
103    };
104}
105
106impl_scheme_string_traits!(TaskId, TaskId::parse);
107impl_scheme_string_traits!(TaskTreeId, TaskTreeId::new);
108impl_string_traits!(TaskNodeId, TaskNodeId::new);