From 561f85fbb059f4fbcf7b82a7ad2b9597886ae99c Mon Sep 17 00:00:00 2001 From: Sebastian Kuzminsky Date: Thu, 3 Jul 2025 11:59:44 -0600 Subject: [PATCH] WIP start adding Issues struct to hold everything --- Cargo.toml | 2 + src/issues.rs | 125 ++++++++++++++++++ src/lib.rs | 1 + .../state | 1 + .../title | 1 + test/0001/config.toml | 1 + .../description | 4 + .../state | 1 + .../title | 1 + 9 files changed, 137 insertions(+) create mode 100644 src/issues.rs create mode 100644 test/0001/3fa5bfd93317ad25772680071d5ac3259cd2384f/state create mode 100644 test/0001/3fa5bfd93317ad25772680071d5ac3259cd2384f/title create mode 100644 test/0001/config.toml create mode 100644 test/0001/dd79c8cfb8beeacd0460429944b4ecbe95a31561/description create mode 100644 test/0001/dd79c8cfb8beeacd0460429944b4ecbe95a31561/state create mode 100644 test/0001/dd79c8cfb8beeacd0460429944b4ecbe95a31561/title diff --git a/Cargo.toml b/Cargo.toml index 905a9b5..2230bb4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,6 @@ version = "0.1.0" edition = "2024" [dependencies] +serde = { version = "1.0.217", features = ["derive"] } thiserror = "2.0.11" +toml = "0.8.19" diff --git a/src/issues.rs b/src/issues.rs new file mode 100644 index 0000000..b5c1c87 --- /dev/null +++ b/src/issues.rs @@ -0,0 +1,125 @@ +// Just a placeholder for now, get rid of this if we don't need it. +#[derive(Debug, PartialEq, serde::Deserialize)] +pub struct Config {} + +#[derive(Debug, PartialEq)] +pub struct Issues { + pub issues: std::collections::HashMap, + pub config: Config, +} + +#[derive(Debug, thiserror::Error)] +pub enum ReadIssuesError { + #[error(transparent)] + StdIoError(#[from] std::io::Error), + #[error("Failed to parse issue")] + IssueParseError(#[from] crate::issue::ReadIssueError), + #[error("cannot handle filename")] + FilenameError(std::ffi::OsString), + #[error(transparent)] + TomlDeserializeError(#[from] toml::de::Error), +} + +impl Issues { + pub fn new() -> Self { + Self { + issues: std::collections::HashMap::new(), + config: Config {}, + } + } + + pub fn add_issue(&mut self, uuid: String, issue: crate::issue::Issue) { + self.issues.insert(uuid, issue); + } + + fn parse_config(&mut self, config_path: &std::path::Path) -> Result<(), ReadIssuesError> { + let config_contents = std::fs::read_to_string(config_path)?; + let config: Config = toml::from_str(&config_contents)?; + self.config = config; + Ok(()) + } + + pub fn new_from_dir(dir: &std::path::Path) -> Result { + let mut issues = Self::new(); + + 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(uuid, issue); + } else if direntry.file_name() == "config.toml" { + issues.parse_config(direntry.path().as_path())?; + } else { + println!( + "ignoring unknown file in issues directory: {:?}", + direntry.file_name() + ); + } + } + } + return Ok(issues); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn read_issues_0000() { + let issues_dir = std::path::Path::new("test/0000/"); + let issues = Issues::new_from_dir(issues_dir).unwrap(); + + let mut expected = Issues::new(); + expected.add_issue( + String::from("7792b063eef6d33e7da5dc1856750c149ba678c6"), + crate::issue::Issue { + title: String::from("minimal"), + description: None, + state: crate::issue::State::InProgress, + }, + ); + expected.add_issue( + String::from("3943fc5c173fdf41c0a22251593cd476d96e6c9f"), + crate::issue::Issue { + title: String::from("this is the title of my issue"), + description: Some(String::from("This is the description of my issue.\nIt is multiple lines.\n* Arbitrary contents\n* But let's use markdown by convention\n")), + state: crate::issue::State::New, + } + ); + assert_eq!(issues, expected); + } + + #[test] + fn read_issues_0001() { + let issues_dir = std::path::Path::new("test/0001/"); + let issues = Issues::new_from_dir(issues_dir).unwrap(); + + let mut expected = Issues::new(); + expected.add_issue( + String::from("3fa5bfd93317ad25772680071d5ac3259cd2384f"), + crate::issue::Issue { + title: String::from("oh yeah we got titles"), + description: None, + state: crate::issue::State::Done, + }, + ); + expected.add_issue( + String::from("dd79c8cfb8beeacd0460429944b4ecbe95a31561"), + crate::issue::Issue { + title: String::from("issues out the wazoo"), + description: Some(String::from( + "Lots of words\nthat don't say much\nbecause this is just\na test\n", + )), + state: crate::issue::State::WontDo, + }, + ); + assert_eq!(issues, expected); + } +} diff --git a/src/lib.rs b/src/lib.rs index d93d369..713acd1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1 +1,2 @@ pub mod issue; +pub mod issues; diff --git a/test/0001/3fa5bfd93317ad25772680071d5ac3259cd2384f/state b/test/0001/3fa5bfd93317ad25772680071d5ac3259cd2384f/state new file mode 100644 index 0000000..19f86f4 --- /dev/null +++ b/test/0001/3fa5bfd93317ad25772680071d5ac3259cd2384f/state @@ -0,0 +1 @@ +done diff --git a/test/0001/3fa5bfd93317ad25772680071d5ac3259cd2384f/title b/test/0001/3fa5bfd93317ad25772680071d5ac3259cd2384f/title new file mode 100644 index 0000000..18a1926 --- /dev/null +++ b/test/0001/3fa5bfd93317ad25772680071d5ac3259cd2384f/title @@ -0,0 +1 @@ +oh yeah we got titles diff --git a/test/0001/config.toml b/test/0001/config.toml new file mode 100644 index 0000000..dfc15f2 --- /dev/null +++ b/test/0001/config.toml @@ -0,0 +1 @@ +states = [ "open", "closed" ] diff --git a/test/0001/dd79c8cfb8beeacd0460429944b4ecbe95a31561/description b/test/0001/dd79c8cfb8beeacd0460429944b4ecbe95a31561/description new file mode 100644 index 0000000..010156b --- /dev/null +++ b/test/0001/dd79c8cfb8beeacd0460429944b4ecbe95a31561/description @@ -0,0 +1,4 @@ +Lots of words +that don't say much +because this is just +a test diff --git a/test/0001/dd79c8cfb8beeacd0460429944b4ecbe95a31561/state b/test/0001/dd79c8cfb8beeacd0460429944b4ecbe95a31561/state new file mode 100644 index 0000000..7f19192 --- /dev/null +++ b/test/0001/dd79c8cfb8beeacd0460429944b4ecbe95a31561/state @@ -0,0 +1 @@ +wontdo diff --git a/test/0001/dd79c8cfb8beeacd0460429944b4ecbe95a31561/title b/test/0001/dd79c8cfb8beeacd0460429944b4ecbe95a31561/title new file mode 100644 index 0000000..ab5b4a9 --- /dev/null +++ b/test/0001/dd79c8cfb8beeacd0460429944b4ecbe95a31561/title @@ -0,0 +1 @@ +issues out the wazoo