1#[cfg(doc)]
22use crate::entry::Entry;
23use crate::entry::{EntryError, MARKER_RE};
24
25#[derive(Debug, Clone, Copy, Eq, PartialEq)]
27pub enum EntryKind {
28 Start,
30 Stop,
32 Ignored,
34 Event
36}
37
38impl From<EntryKind> for char {
39 fn from(k: EntryKind) -> char {
41 match k {
42 EntryKind::Start | EntryKind::Stop => ' ',
43 EntryKind::Ignored => '!',
44 EntryKind::Event => '^'
45 }
46 }
47}
48
49impl EntryKind {
50 pub fn new<KC>(mark: KC) -> Self
53 where
54 KC: Into<Option<char>>
55 {
56 Self::try_new(mark).unwrap_or(Self::Start)
57 }
58
59 pub fn try_new<KC>(mark: KC) -> Result<Self, EntryError>
65 where
66 KC: Into<Option<char>>
67 {
68 match mark.into() {
69 Some(' ') | None => Ok(Self::Start),
70 Some('!') => Ok(Self::Ignored),
71 Some('^') => Ok(Self::Event),
72 Some(_) => Err(EntryError::InvalidMarker)
73 }
74 }
75
76 pub fn from_entry_line(line: &str) -> Self {
78 let marker = MARKER_RE.captures(line)
79 .map(|cap| cap.get(1).and_then(|m| m.as_str().chars().next()));
80 Self::new(marker.flatten())
81 }
82
83 pub fn is_start(&self) -> bool { *self == Self::Start }
85
86 pub fn is_ignored(&self) -> bool { *self == Self::Ignored }
88
89 pub fn is_event(&self) -> bool { *self == Self::Event }
91
92 pub fn is_stop(&self) -> bool { *self == Self::Stop }
94}
95
96#[cfg(test)]
97mod tests {
98 use spectral::prelude::*;
99
100 use super::*;
101
102 #[test]
103 #[rustfmt::skip]
104 fn try_new_successes() {
105 assert_that!(EntryKind::try_new(None)).is_ok().is_equal_to(EntryKind::Start);
106 assert_that!(EntryKind::try_new(' ')).is_ok().is_equal_to(EntryKind::Start);
107 assert_that!(EntryKind::try_new('!')).is_ok().is_equal_to(EntryKind::Ignored);
108 assert_that!(EntryKind::try_new('^')).is_ok().is_equal_to(EntryKind::Event);
109 }
110
111 #[test]
112 fn try_new_fails() {
113 assert_that!(EntryKind::try_new('a')).is_err();
114 assert_that!(EntryKind::try_new('8')).is_err();
115 assert_that!(EntryKind::try_new('*')).is_err();
116 }
117
118 #[test]
119 fn new_never_fails() {
120 assert_that!(EntryKind::new(None)).is_equal_to(EntryKind::Start);
121 assert_that!(EntryKind::new(' ')).is_equal_to(EntryKind::Start);
122 assert_that!(EntryKind::new('!')).is_equal_to(EntryKind::Ignored);
123 assert_that!(EntryKind::new('^')).is_equal_to(EntryKind::Event);
124 assert_that!(EntryKind::new('a')).is_equal_to(EntryKind::Start);
125 assert_that!(EntryKind::new('8')).is_equal_to(EntryKind::Start);
126 assert_that!(EntryKind::new('*')).is_equal_to(EntryKind::Start);
127 }
128
129 #[test]
130 fn char_from_kind() {
131 assert_that!(char::from(EntryKind::Start)).is_equal_to(' ');
132 assert_that!(char::from(EntryKind::Stop)).is_equal_to(' ');
133 assert_that!(char::from(EntryKind::Ignored)).is_equal_to('!');
134 assert_that!(char::from(EntryKind::Event)).is_equal_to('^');
135 }
136
137 #[test]
138 fn from_entry_line_on_start() {
139 #[rustfmt::skip]
140 assert_that!(EntryKind::from_entry_line("2013-06-05 10:00:02 +test @Commented"))
141 .is_equal_to(EntryKind::Start);
142 }
143
144 #[test]
145 fn from_entry_line_on_ignored() {
146 #[rustfmt::skip]
147 assert_that!(EntryKind::from_entry_line("2013-06-05 10:00:02!+test @Ignored"))
148 .is_equal_to(EntryKind::Ignored);
149 }
150
151 #[test]
152 fn from_entry_line_on_pin() {
153 #[rustfmt::skip]
154 assert_that!(EntryKind::from_entry_line("2013-06-05 10:00:02^+test @Event"))
155 .is_equal_to(EntryKind::Event);
156 }
157
158 #[test]
159 fn get_line_entry_kind_on_comment() {
160 #[rustfmt::skip]
161 assert_that!(EntryKind::from_entry_line("#2013-06-05 10:00:02 +test @Commented"))
162 .is_equal_to(EntryKind::Start);
163 }
164}