dbc_rs/nodes/
nodes_builder.rs1use crate::{error::Error, error::Result, nodes::Nodes};
2
3#[derive(Debug, Default)]
4pub struct NodesBuilder {
5 nodes: Vec<String>,
6}
7
8impl NodesBuilder {
9 pub fn new() -> Self {
10 Self::default()
11 }
12
13 #[must_use]
14 pub fn add_node(mut self, node: impl AsRef<str>) -> Self {
15 self.nodes.push(node.as_ref().to_string());
16 self
17 }
18
19 #[must_use]
20 pub fn add_nodes<I, S>(mut self, nodes: I) -> Self
21 where
22 I: IntoIterator<Item = S>,
23 S: AsRef<str>,
24 {
25 self.nodes.extend(nodes.into_iter().map(|s| s.as_ref().to_string()));
26 self
27 }
28
29 #[must_use]
30 pub fn clear(mut self) -> Self {
31 self.nodes.clear();
32 self
33 }
34
35 fn extract_and_validate_nodes(self) -> Result<Vec<String>> {
36 let node_strs: Vec<String> = self.nodes.into_iter().map(|s| s.to_string()).collect();
37 let node_refs: Vec<&str> = node_strs.iter().map(|s| s.as_str()).collect();
38 super::Nodes::validate_nodes(&node_refs).map_err(|e| match e {
39 crate::error::ParseError::Version(msg) => Error::Nodes(String::from(msg)),
40 _ => Error::from(e),
41 })?;
42 Ok(node_strs)
43 }
44
45 #[must_use = "validation result should be checked"]
46 pub fn validate(self) -> Result<Self> {
47 let node_strs = self.extract_and_validate_nodes()?;
48 Ok(Self { nodes: node_strs })
49 }
50
51 pub fn build(self) -> Result<Nodes<'static>> {
52 let node_strs = self.extract_and_validate_nodes()?;
53 let mut node_refs: Vec<&'static str> = Vec::new();
56 for s in node_strs {
57 let boxed: Box<str> = s.into_boxed_str();
58 node_refs.push(Box::leak(boxed));
59 }
60 super::Nodes::validate_nodes(&node_refs).map_err(|e| match e {
62 crate::error::ParseError::Version(msg) => Error::Nodes(String::from(msg)),
63 _ => Error::from(e),
64 })?;
65 Ok(Nodes::new(&node_refs))
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 #![allow(clippy::float_cmp)]
72 use super::*;
73 use crate::{error::Error, error::lang};
74
75 #[test]
76 fn test_nodes_builder_duplicate() {
77 let result = NodesBuilder::new().add_node("ECM").add_node("TCM").add_node("ECM").build();
78 assert!(result.is_err());
79 match result.unwrap_err() {
80 Error::Nodes(msg) => assert!(msg.contains(lang::NODES_DUPLICATE_NAME)),
81 _ => panic!("Expected Nodes error"),
82 }
83 }
84
85 #[test]
86 fn test_nodes_builder_too_many() {
87 let mut builder = NodesBuilder::new();
88 for i in 0..257 {
89 builder = builder.add_node(format!("Node{i}"));
90 }
91 let result = builder.build();
92 assert!(result.is_err());
93 match result.unwrap_err() {
94 Error::Nodes(msg) => {
95 assert!(msg.contains(lang::NODES_TOO_MANY));
96 }
97 _ => panic!("Expected Nodes error"),
98 }
99 }
100}