diff --git a/src/issue.rs b/src/issue.rs index 0de413c..1558578 100644 --- a/src/issue.rs +++ b/src/issue.rs @@ -20,7 +20,6 @@ pub type IssueHandle = String; #[derive(Debug, PartialEq)] pub struct Issue { - pub id: String, pub author: String, pub timestamp: chrono::DateTime, pub tags: Vec, @@ -57,8 +56,6 @@ pub enum IssueError { TagNotFound(String), #[error("stdin/stdout is not a terminal")] StdioIsNotTerminal, - #[error("Failed to parse issue ID")] - IdError, } impl FromStr for State { @@ -148,21 +145,10 @@ impl Issue { return Err(IssueError::IssueParseError); } - // parse the issue ID from the directory name - let id = if let Some(parsed_id) = match dir.file_name() { - Some(name) => name.to_str(), - None => Err(IssueError::IdError)?, - } { - String::from(parsed_id) - } else { - Err(IssueError::IdError)? - }; - let author = crate::git::git_log_oldest_author(dir)?; let timestamp = crate::git::git_log_oldest_timestamp(dir)?; Ok(Self { - id, author, timestamp, tags, @@ -218,7 +204,6 @@ impl Issue { std::fs::create_dir(&issue_dir)?; let mut issue = Self { - id: String::from(&issue_id), author: String::from(""), timestamp: chrono::Local::now(), tags: Vec::::new(), @@ -459,7 +444,6 @@ mod tests { let issue_dir = std::path::Path::new("test/0000/3943fc5c173fdf41c0a22251593cd476d96e6c9f/"); let issue = Issue::new_from_dir(issue_dir).unwrap(); let expected = Issue { - id: String::from("3943fc5c173fdf41c0a22251593cd476d96e6c9f"), author: String::from("Sebastian Kuzminsky "), timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-03T12:14:26-06:00") .unwrap() @@ -467,14 +451,12 @@ mod tests { tags: Vec::::from([ String::from("tag1"), String::from("TAG2"), - String::from("i-am-also-a-tag"), + String::from("i-am-also-a-tag") ]), state: State::New, dependencies: None, assignee: None, - description: String::from( - "this is the title of my issue\n\nThis is the description of my issue.\nIt is multiple lines.\n* Arbitrary contents\n* But let's use markdown by convention\n", - ), + description: String::from("this is the title of my issue\n\nThis is the description of my issue.\nIt is multiple lines.\n* Arbitrary contents\n* But let's use markdown by convention\n"), comments: Vec::::new(), dir: std::path::PathBuf::from(issue_dir), }; @@ -486,7 +468,6 @@ mod tests { let issue_dir = std::path::Path::new("test/0000/7792b063eef6d33e7da5dc1856750c149ba678c6/"); let issue = Issue::new_from_dir(issue_dir).unwrap(); let expected = Issue { - id: String::from("7792b063eef6d33e7da5dc1856750c149ba678c6"), author: String::from("Sebastian Kuzminsky "), timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-03T12:14:26-06:00") .unwrap() diff --git a/src/issues.rs b/src/issues.rs index 42e964d..5c314ac 100644 --- a/src/issues.rs +++ b/src/issues.rs @@ -31,8 +31,8 @@ impl Issues { } } - pub fn add_issue(&mut self, issue: crate::issue::Issue) { - self.issues.insert(issue.id.clone(), issue); + pub fn add_issue(&mut self, uuid: String, issue: crate::issue::Issue) { + self.issues.insert(uuid, issue); } pub fn get_issue(&self, issue_id: &str) -> Option<&crate::issue::Issue> { @@ -56,8 +56,14 @@ impl Issues { for direntry in dir.read_dir()? { if let Ok(direntry) = direntry { if direntry.metadata()?.is_dir() { + let uuid = match direntry.file_name().into_string() { + Ok(uuid) => uuid, + Err(orig_string) => { + return Err(ReadIssuesError::FilenameError(orig_string)) + } + }; let issue = crate::issue::Issue::new_from_dir(direntry.path().as_path())?; - issues.add_issue(issue); + issues.add_issue(uuid, issue); } else if direntry.file_name() == "config.toml" { issues.parse_config(direntry.path().as_path())?; } else { @@ -87,27 +93,29 @@ mod tests { let uuid = String::from("7792b063eef6d33e7da5dc1856750c149ba678c6"); let mut dir = std::path::PathBuf::from(issues_dir); dir.push(&uuid); - expected.add_issue(crate::issue::Issue { - id: uuid, - author: String::from("Sebastian Kuzminsky "), - timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-03T12:14:26-06:00") - .unwrap() - .with_timezone(&chrono::Local), - tags: Vec::::new(), - state: crate::issue::State::InProgress, - dependencies: None, - assignee: Some(String::from("beep boop")), - description: String::from("minimal"), - comments: Vec::::new(), - dir, - }); + expected.add_issue( + uuid, + crate::issue::Issue { + author: String::from("Sebastian Kuzminsky "), + timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-03T12:14:26-06:00") + .unwrap() + .with_timezone(&chrono::Local), + tags: Vec::::new(), + state: crate::issue::State::InProgress, + dependencies: None, + assignee: Some(String::from("beep boop")), + description: String::from("minimal"), + comments: Vec::::new(), + dir, + }, + ); let uuid = String::from("3943fc5c173fdf41c0a22251593cd476d96e6c9f"); let mut dir = std::path::PathBuf::from(issues_dir); dir.push(&uuid); expected.add_issue( + uuid, crate::issue::Issue { - id: uuid, author: String::from("Sebastian Kuzminsky "), timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-03T12:14:26-06:00") .unwrap() @@ -138,20 +146,22 @@ mod tests { let uuid = String::from("3fa5bfd93317ad25772680071d5ac3259cd2384f"); let mut dir = std::path::PathBuf::from(issues_dir); dir.push(&uuid); - expected.add_issue(crate::issue::Issue { - id: uuid, - author: String::from("Sebastian Kuzminsky "), - timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-03T11:59:44-06:00") - .unwrap() - .with_timezone(&chrono::Local), - tags: Vec::::new(), - state: crate::issue::State::Done, - dependencies: None, - assignee: None, - description: String::from("oh yeah we got titles"), - comments: Vec::::new(), - dir, - }); + expected.add_issue( + uuid, + crate::issue::Issue { + author: String::from("Sebastian Kuzminsky "), + timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-03T11:59:44-06:00") + .unwrap() + .with_timezone(&chrono::Local), + tags: Vec::::new(), + state: crate::issue::State::Done, + dependencies: None, + assignee: None, + description: String::from("oh yeah we got titles"), + comments: Vec::::new(), + dir, + }, + ); let uuid = String::from("dd79c8cfb8beeacd0460429944b4ecbe95a31561"); let mut dir = std::path::PathBuf::from(issues_dir); @@ -171,8 +181,8 @@ mod tests { } ); expected.add_issue( + uuid, crate::issue::Issue { - id: uuid, author: String::from("Sebastian Kuzminsky "), timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-03T11:59:44-06:00") .unwrap() @@ -199,27 +209,29 @@ mod tests { let uuid = String::from("3fa5bfd93317ad25772680071d5ac3259cd2384f"); let mut dir = std::path::PathBuf::from(issues_dir); dir.push(&uuid); - expected.add_issue(crate::issue::Issue { - id: uuid, - author: String::from("sigil-03 "), - timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-05T13:55:49-06:00") - .unwrap() - .with_timezone(&chrono::Local), - tags: Vec::::new(), - state: crate::issue::State::Done, - dependencies: None, - assignee: None, - description: String::from("oh yeah we got titles\n"), - comments: Vec::::new(), - dir, - }); + expected.add_issue( + uuid, + crate::issue::Issue { + author: String::from("sigil-03 "), + timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-05T13:55:49-06:00") + .unwrap() + .with_timezone(&chrono::Local), + tags: Vec::::new(), + state: crate::issue::State::Done, + dependencies: None, + assignee: None, + description: String::from("oh yeah we got titles\n"), + comments: Vec::::new(), + dir, + }, + ); let uuid = String::from("dd79c8cfb8beeacd0460429944b4ecbe95a31561"); let mut dir = std::path::PathBuf::from(issues_dir); dir.push(&uuid); expected.add_issue( + uuid, crate::issue::Issue { - id: uuid, author: String::from("sigil-03 "), timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-05T13:55:49-06:00") .unwrap() @@ -238,8 +250,8 @@ mod tests { let mut dir = std::path::PathBuf::from(issues_dir); dir.push(&uuid); expected.add_issue( + uuid, crate::issue::Issue { - id: uuid, author: String::from("sigil-03 "), timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-05T13:55:49-06:00") .unwrap()