keydata/section.rs
1use std::collections::HashMap;
2/// A Section to hold keynote file entries (key-value pairs)
3pub struct Section {
4 /// name of the Section
5 pub name : String,
6 /// hashmap to hold key value pairs that make up entries
7 pub data : HashMap<String, String>
8}
9
10impl Section {
11 /// Returns a Section with the name given
12 ///
13 /// # Arguments
14 ///
15 /// * `name` - section name as string slice
16 ///
17 /// # Examples ///
18 /// ```
19 /// use keydata::Section;
20 /// let s = Section::new("test_section");
21 /// assert_eq!(s.name, "test_section");
22 /// assert_eq!(s.data.len(), 0);
23 /// ```
24 pub fn new(name : &str) -> Section {
25 Section {
26 name: name.to_string(),
27 data : HashMap::new()
28 }
29 }
30
31 /// Formats a string into the form it appears as in the data file
32 ///
33 /// # Arguments
34 ///
35 /// * `section_name` - name of section to format as string slice
36 ///
37 /// # Examples ///
38 /// ```
39 /// use keydata::Section;
40 /// let s = Section::build_section_string("test_section");
41 /// assert_eq!(s, "<test_section>\n");
42 /// ```
43 pub fn build_section_string(section_name: &str) -> String {
44 let mut header_string = String::new();
45 header_string.push('<');
46 header_string.push_str(section_name);
47 header_string.push_str(">\n");
48
49 header_string
50 }
51
52 /// Returns name of a section from formatted section string. None if line is not valid section string;
53 ///
54 /// # Arguments
55 ///
56 /// * `line` - string slice containing section string
57 ///
58 /// # Examples ///
59 /// ```
60 /// use keydata::Section;
61 /// let line = "<test_section>\n";
62 /// let sn = Section::get_section_name_from_string(line);
63 /// assert!(sn.is_some());
64 /// assert_eq!(sn.unwrap(), "test_section");
65 /// ```
66 pub fn get_section_name_from_string(line : &str) -> Option<&str> {
67 if !line.starts_with("<") || !line.contains(">") || line.contains("\t") { // not a valid section name
68 return None
69 }
70
71 let chars_to_subtract = if line.ends_with("\n") { 2 } else { 1 };
72
73 // len - 2 excludes the newline and the '>'
74 Some(&line[1..line.len()-chars_to_subtract])
75 }
76
77 /// Adds a key-value pair entry to the Sections data
78 ///
79 /// # Arguments
80 ///
81 /// * `key` - entry key as string slice
82 /// * `value` - entry value as string slice
83 ///
84 /// # Examples ///
85 /// ```
86 /// use keydata::Section;
87 /// let mut s = Section::new("test_section");
88 /// assert_eq!(s.data.len(), 0);
89 ///
90 /// s.add_entry("theKey", "theValue");
91 /// assert_eq!(s.data.len(), 1);
92 /// assert_eq!(s.data.get("theKey").unwrap(), "theValue");
93 /// ```
94 pub fn add_entry(&mut self, key: &str, value: &str) {
95 self.data.insert(key.to_string(), value.to_string());
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[test]
104 fn new_success() {
105 let name = "section_name";
106
107 let section = Section::new(name);
108
109 assert_eq!(section.name, name);
110 assert!(section.data.len() == 0);
111 }
112
113 #[test]
114 fn build_section_string_success() {
115 let result = Section::build_section_string("test");
116 assert_eq!(result, "<test>\n");
117 }
118
119 #[test]
120 fn get_section_name_from_string_success() {
121 let result = Section::get_section_name_from_string("<test_section>\n");
122 assert!(result.is_some());
123 assert_eq!(result.unwrap(), "test_section");
124 }
125
126 #[test]
127 fn get_section_name_from_string_no_newline_expect_none() {
128 let result = Section::get_section_name_from_string("<test_section>");
129 assert!(result.is_some());
130 assert_eq!(result.unwrap(), "test_section");
131 }
132
133 #[test]
134 fn get_section_name_from_string_invalid_start_expect_none() {
135 let result = Section::get_section_name_from_string("test_section>");
136 assert!(result.is_none());
137 }
138
139 #[test]
140 fn get_section_name_from_string_missing_piece_expect_none() {
141 let result = Section::get_section_name_from_string("<test_section\n");
142 assert!(result.is_none());
143 }
144
145 #[test]
146 fn add_entry_success() {
147 let mut section = Section::new("test_section");
148 assert!(section.data.len() == 0);
149
150 section.add_entry("test_key", "test_value");
151
152 assert!(section.data.len() == 1);
153 assert_eq!(section.data.get("test_key").unwrap(), "test_value");
154 }
155}