1#[derive(Clone, Debug)]
2#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
4#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
5#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
6pub struct TodoList {
7 #[cfg_attr(feature = "serde", serde(default = "init_default"))]
8 pub init: bool,
9 #[cfg_attr(feature = "serde", serde(default))]
10 #[cfg_attr(
11 feature = "serde",
12 serde(serialize_with = "humantime_serde::serialize")
13 )]
14 #[cfg_attr(
15 feature = "serde",
16 serde(deserialize_with = "humantime_serde::deserialize")
17 )]
18 pub sleep: Option<std::time::Duration>,
19 #[cfg_attr(feature = "serde", serde(default))]
20 pub author: Option<String>,
21 #[cfg_attr(feature = "serde", serde(default))]
22 pub commands: Vec<Command>,
23}
24
25fn init_default() -> bool {
26 true
27}
28
29impl Default for TodoList {
30 fn default() -> Self {
31 Self {
32 init: init_default(),
33 sleep: None,
34 author: None,
35 commands: Vec::new(),
36 }
37 }
38}
39
40#[derive(Clone, Debug, derive_more::IsVariant)]
41#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
42#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
43#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
44#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
45pub enum Command {
46 Label(Label),
47 Reset(Label),
48 Tree(Tree),
49 Merge(Merge),
50 Branch(Branch),
51 Tag(Tag),
52 Head,
53}
54
55impl From<Tree> for Command {
56 fn from(tree: Tree) -> Self {
57 Self::Tree(tree)
58 }
59}
60
61#[derive(Default, Clone, Debug)]
62#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
63#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
64#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
65#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
66pub struct Tree {
67 pub files: std::collections::HashMap<std::path::PathBuf, FileContent>,
68 #[cfg_attr(feature = "serde", serde(default))]
69 pub message: Option<String>,
70 #[cfg_attr(feature = "serde", serde(default))]
71 pub author: Option<String>,
72}
73
74#[derive(Clone, Debug, derive_more::IsVariant)]
75#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
76#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
77#[cfg_attr(feature = "serde", serde(untagged))]
78#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
79#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
80pub enum FileContent {
81 Binary(Vec<u8>),
82 Text(String),
83}
84
85impl FileContent {
86 pub fn as_bytes(&self) -> &[u8] {
87 match self {
88 FileContent::Binary(v) => v.as_slice(),
89 FileContent::Text(v) => v.as_bytes(),
90 }
91 }
92}
93
94impl From<String> for FileContent {
95 fn from(data: String) -> Self {
96 Self::Text(data)
97 }
98}
99
100impl<'d> From<&'d String> for FileContent {
101 fn from(data: &'d String) -> Self {
102 Self::Text(data.clone())
103 }
104}
105
106impl<'d> From<&'d str> for FileContent {
107 fn from(data: &'d str) -> Self {
108 Self::Text(data.to_owned())
109 }
110}
111
112#[derive(Clone, Debug)]
113#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
114#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
115#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
116#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
117pub struct Merge {
118 pub base: Vec<Label>,
119 #[cfg_attr(feature = "serde", serde(default))]
120 pub message: Option<String>,
121 #[cfg_attr(feature = "serde", serde(default))]
122 pub author: Option<String>,
123}
124
125#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
126#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
127#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
128#[cfg_attr(feature = "serde", serde(transparent))]
129pub struct Label(String);
130
131impl Label {
132 pub fn new(name: &str) -> Self {
133 Self(name.to_owned())
134 }
135
136 pub fn as_str(&self) -> &str {
137 self.0.as_str()
138 }
139}
140
141impl From<String> for Label {
142 fn from(other: String) -> Self {
143 Self(other)
144 }
145}
146
147impl<'s> From<&'s str> for Label {
148 fn from(other: &'s str) -> Self {
149 Self(other.to_owned())
150 }
151}
152
153impl std::ops::Deref for Label {
154 type Target = str;
155
156 #[inline]
157 fn deref(&self) -> &str {
158 self.as_str()
159 }
160}
161
162impl std::borrow::Borrow<str> for Label {
163 #[inline]
164 fn borrow(&self) -> &str {
165 self.as_str()
166 }
167}
168
169impl std::fmt::Display for Label {
170 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
171 self.as_str().fmt(f)
172 }
173}
174
175#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
176#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
177#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
178#[cfg_attr(feature = "serde", serde(transparent))]
179pub struct Branch(String);
180
181impl Branch {
182 pub fn new(name: &str) -> Self {
183 Self(name.to_owned())
184 }
185
186 pub fn as_str(&self) -> &str {
187 self.0.as_str()
188 }
189}
190
191impl From<String> for Branch {
192 fn from(other: String) -> Self {
193 Self(other)
194 }
195}
196
197impl<'s> From<&'s str> for Branch {
198 fn from(other: &'s str) -> Self {
199 Self(other.to_owned())
200 }
201}
202
203impl std::ops::Deref for Branch {
204 type Target = str;
205
206 #[inline]
207 fn deref(&self) -> &str {
208 self.as_str()
209 }
210}
211
212impl std::borrow::Borrow<str> for Branch {
213 #[inline]
214 fn borrow(&self) -> &str {
215 self.as_str()
216 }
217}
218
219impl std::fmt::Display for Branch {
220 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
221 self.as_str().fmt(f)
222 }
223}
224
225#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
226#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
227#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
228#[cfg_attr(feature = "serde", serde(transparent))]
229pub struct Tag(String);
230
231impl Tag {
232 pub fn new(name: &str) -> Self {
233 Self(name.to_owned())
234 }
235
236 pub fn as_str(&self) -> &str {
237 self.0.as_str()
238 }
239}
240
241impl From<String> for Tag {
242 fn from(other: String) -> Self {
243 Self(other)
244 }
245}
246
247impl<'s> From<&'s str> for Tag {
248 fn from(other: &'s str) -> Self {
249 Self(other.to_owned())
250 }
251}
252
253impl std::ops::Deref for Tag {
254 type Target = str;
255
256 #[inline]
257 fn deref(&self) -> &str {
258 self.as_str()
259 }
260}
261
262impl std::borrow::Borrow<str> for Tag {
263 #[inline]
264 fn borrow(&self) -> &str {
265 self.as_str()
266 }
267}
268
269impl std::fmt::Display for Tag {
270 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
271 self.as_str().fmt(f)
272 }
273}