1use serde::{Deserialize, Serialize};
2use ts_rs::TS;
3
4#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, TS)]
5#[ts(export)]
6pub struct TaskId(pub String);
7
8impl TaskId {
9 pub fn new(board_prefix: &str, seq: u64) -> Self {
10 Self(format!("{}-{}", board_prefix.to_uppercase(), seq))
11 }
12
13 pub fn parse(s: &str) -> Result<Self, String> {
14 let parts: Vec<&str> = s.split('-').collect();
15 if parts.len() != 2 {
16 return Err(format!("Invalid task ID format: '{}'. Expected 'PREFIX-NUMBER'", s));
17 }
18 let prefix = parts[0].to_uppercase();
19 if !prefix.chars().all(|c| c.is_ascii_uppercase()) {
20 return Err(format!("Invalid board prefix: '{}'. Must be letters", prefix));
21 }
22 let seq: u64 = parts[1].parse().map_err(|_| {
23 format!("Invalid sequence number: '{}'. Must be a positive integer", parts[1])
24 })?;
25 Ok(Self(format!("{}-{}", prefix, seq)))
26 }
27
28 pub fn board_prefix(&self) -> Option<&str> {
29 self.0.split('-').next()
30 }
31
32 pub fn sequence(&self) -> Option<u64> {
33 self.0.split('-').nth(1)?.parse().ok()
34 }
35}
36
37impl From<&str> for TaskId {
38 fn from(s: &str) -> Self {
39 TaskId(s.to_string())
40 }
41}
42
43impl From<String> for TaskId {
44 fn from(s: String) -> Self {
45 TaskId(s)
46 }
47}
48
49impl std::fmt::Display for TaskId {
50 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51 write!(f, "{}", self.0)
52 }
53}
54
55impl AsRef<str> for TaskId {
56 fn as_ref(&self) -> &str {
57 &self.0
58 }
59}
60
61#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, TS)]
62#[ts(export)]
63pub struct BoardId(pub String);
64
65impl From<&str> for BoardId {
66 fn from(s: &str) -> Self {
67 BoardId(s.to_string())
68 }
69}
70
71impl From<String> for BoardId {
72 fn from(s: String) -> Self {
73 BoardId(s)
74 }
75}
76
77impl std::fmt::Display for BoardId {
78 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79 write!(f, "{}", self.0)
80 }
81}
82
83impl AsRef<str> for BoardId {
84 fn as_ref(&self) -> &str {
85 &self.0
86 }
87}