diff --git a/README.md b/README.md index 5373f28..ae840c4 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ A collection of resources and code snippets for learning rust. 1. [Accumulate](exercism-solutions/rust/accumulate/src/lib.rs) ❌ 2. [Custom Set](exercism-solutions/rust/custom-set/src/lib.rs) ❌ 3. [Dominoes](exercism-solutions/rust/dominoes/src/lib.rs) ❌ -4. [Dot DSL](exercism-solutions/rust/dot-dsl/src/lib.rs) ❌ +4. [Dot DSL](exercism-solutions/rust/dot-dsl/src/lib.rs) ✔️ 5. [Fizzy](exercism-solutions/rust/fizzy/src/lib.rs) ✔️ 6. [Grep](exercism-solutions/rust/grep/src/lib.rs) ❌ 7. [Hamming](exercism-solutions/rust/hamming/src/lib.rs) ✔️ diff --git a/exercism-solutions/rust/dot-dsl/src/lib.rs b/exercism-solutions/rust/dot-dsl/src/lib.rs index 3f2514d..343507f 100644 --- a/exercism-solutions/rust/dot-dsl/src/lib.rs +++ b/exercism-solutions/rust/dot-dsl/src/lib.rs @@ -1,9 +1,111 @@ pub mod graph { - pub struct Graph; + use std::collections::HashMap; + + use self::graph_items::edge::Edge; + use self::graph_items::node::Node; + + #[derive(Clone)] + pub struct Graph { + pub nodes: Vec, + pub edges: Vec, + pub attrs: HashMap, + } impl Graph { pub fn new() -> Self { - todo!("Construct a new Graph struct."); + Self { + nodes: Vec::default(), + edges: Vec::default(), + attrs: HashMap::default(), + } + } + + pub fn with_nodes(mut self, nodes: &[Node]) -> Self { + self.nodes.append(&mut nodes.to_owned()); + self + } + + pub fn with_edges(mut self, edges: &[Edge]) -> Self { + self.edges.append(&mut edges.to_owned()); + self + } + + pub fn with_attrs(mut self, attrs: &[(&'static str, &'static str)]) -> Self { + self.attrs + .extend(attrs.iter().map(|(k, v)| (k.to_string(), v.to_string()))); + self + } + + pub fn node(&self, node_name: &str) -> Option<&Node> { + self.nodes.iter().find(|node| node.name == node_name) + } + } + + impl Default for Graph { + fn default() -> Self { + Self::new() + } + } + + pub mod graph_items { + pub mod edge { + use std::collections::HashMap; + + #[derive(Clone, Debug, PartialEq)] + pub struct Edge { + pub attrs: HashMap, + pub src: String, + pub dst: String, + } + + impl Edge { + pub fn new(src: &str, dst: &str) -> Self { + Self { + attrs: HashMap::default(), + src: src.to_string(), + dst: dst.to_string(), + } + } + + pub fn with_attrs(mut self, attrs: &[(&'static str, &'static str)]) -> Self { + self.attrs + .extend(attrs.iter().map(|(k, v)| (k.to_string(), v.to_string()))); + self + } + + pub fn attr(&self, attr: &str) -> Option<&str> { + self.attrs.get(&attr.to_string()).map(|x| x.as_str()) + } + } + } + + pub mod node { + use std::collections::HashMap; + + #[derive(Clone, Debug, PartialEq)] + pub struct Node { + pub attrs: HashMap, + pub name: String, + } + + impl Node { + pub fn new(name: &str) -> Self { + Self { + name: name.to_string(), + attrs: HashMap::default(), + } + } + + pub fn with_attrs(mut self, attrs: &[(&'static str, &'static str)]) -> Self { + self.attrs + .extend(attrs.iter().map(|(k, v)| (k.to_string(), v.to_string()))); + self + } + + pub fn attr(&self, attr_name: &str) -> Option<&str> { + self.attrs.get(&attr_name.to_string()).map(|x| x.as_str()) + } + } } } } diff --git a/learning-rust.code-workspace b/learning-rust.code-workspace index 6fa987b..2ad5e9f 100644 --- a/learning-rust.code-workspace +++ b/learning-rust.code-workspace @@ -39,6 +39,8 @@ "./exercism-solutions/rust/hamming/Cargo.toml", "./exercism-solutions/rust/allergies/Cargo.toml", "./exercism-solutions/rust/fizzy/Cargo.toml", + "./exercism-solutions/rust/dot-dsl/Cargo.toml", + "./exercism-solutions/rust/macros/Cargo.toml", "./rust-book/book/Cargo.toml", "./rust-book/minigrep/Cargo.toml", "./rust-book/web-server/Cargo.toml",