obsidian_parser/note/
note_is_todo.rs1use super::Note;
4use crate::prelude::NoteTags;
5
6pub trait NoteIsTodo: Note {
8 fn is_todo(&self) -> Result<bool, Self::Error>;
20}
21
22impl<N> NoteIsTodo for N
23where
24 N: NoteTags,
25{
26 #[cfg_attr(feature = "tracing", tracing::instrument(skip(self), ret, fields(path = format!("{:?}", self.path()))))]
27 fn is_todo(&self) -> Result<bool, N::Error> {
28 let tags = self.tags()?;
29 Ok(tags.contains(&"todo".to_string()))
30 }
31}
32
33#[cfg(test)]
34pub(crate) mod tests {
35 use super::*;
36 use crate::note::{NoteFromFile, NoteFromReader, NoteFromString};
37 use serde::de::DeserializeOwned;
38 use std::io::{Cursor, Write};
39 use tempfile::NamedTempFile;
40
41 const TEST_DATA_HAVE: &str = "---\ntags:\n- todo\n---\nSameData todo";
42 const TEST_DATA_NOT_HAVE: &str = "---\ntags:\n- not_todo\n---\nSameData";
43
44 fn is_todo<N>(note: &N) -> Result<(), N::Error>
45 where
46 N: NoteTags,
47 {
48 assert!(note.is_todo()?);
49 Ok(())
50 }
51
52 fn is_not_todo<N>(note: &N) -> Result<(), N::Error>
53 where
54 N: NoteTags,
55 {
56 assert!(!note.is_todo()?);
57 Ok(())
58 }
59
60 pub(crate) fn from_string_is_todo<N>() -> Result<(), N::Error>
61 where
62 N: NoteFromString + NoteTags,
63 N::Properties: DeserializeOwned,
64 {
65 let note = N::from_string(TEST_DATA_HAVE)?;
66 is_todo(¬e)
67 }
68
69 pub(crate) fn from_string_is_not_todo<N>() -> Result<(), N::Error>
70 where
71 N: NoteFromString + NoteTags,
72 N::Properties: DeserializeOwned,
73 {
74 let note = N::from_string(TEST_DATA_NOT_HAVE)?;
75 is_not_todo(¬e)
76 }
77
78 pub(crate) fn from_reader_is_todo<N>() -> Result<(), N::Error>
79 where
80 N: NoteFromReader + NoteTags,
81 N::Properties: DeserializeOwned,
82 N::Error: From<std::io::Error>,
83 {
84 let note = N::from_reader(&mut Cursor::new(TEST_DATA_HAVE))?;
85 is_todo(¬e)
86 }
87
88 pub(crate) fn from_reader_is_not_todo<N>() -> Result<(), N::Error>
89 where
90 N: NoteFromReader + NoteTags,
91 N::Properties: DeserializeOwned,
92 N::Error: From<std::io::Error>,
93 {
94 let note = N::from_reader(&mut Cursor::new(TEST_DATA_NOT_HAVE))?;
95 is_not_todo(¬e)
96 }
97
98 pub(crate) fn from_file_is_todo<N>() -> Result<(), N::Error>
99 where
100 N: NoteFromFile + NoteTags,
101 N::Properties: DeserializeOwned,
102 N::Error: From<std::io::Error>,
103 {
104 let mut file = NamedTempFile::new().unwrap();
105 file.write_all(TEST_DATA_HAVE.as_bytes()).unwrap();
106
107 let note = N::from_file(file.path())?;
108 is_todo(¬e)
109 }
110
111 pub(crate) fn from_file_is_not_todo<N>() -> Result<(), N::Error>
112 where
113 N: NoteFromFile + NoteTags,
114 N::Properties: DeserializeOwned,
115 N::Error: From<std::io::Error>,
116 {
117 let mut file = NamedTempFile::new().unwrap();
118 file.write_all(TEST_DATA_NOT_HAVE.as_bytes()).unwrap();
119
120 let note = N::from_file(file.path())?;
121 is_not_todo(¬e)
122 }
123
124 macro_rules! impl_all_tests_is_todo {
125 ($impl_note:path) => {
126 #[allow(unused_imports)]
127 use $crate::note::note_is_todo::tests::*;
128
129 impl_test_for_note!(impl_from_string_is_todo, from_string_is_todo, $impl_note);
130 impl_test_for_note!(
131 impl_from_string_is_not_todo,
132 from_string_is_not_todo,
133 $impl_note
134 );
135
136 impl_test_for_note!(impl_from_reader_is_todo, from_reader_is_todo, $impl_note);
137 impl_test_for_note!(
138 impl_from_reader_is_not_todo,
139 from_reader_is_not_todo,
140 $impl_note
141 );
142
143 impl_test_for_note!(impl_from_file_is_todo, from_file_is_todo, $impl_note);
144 impl_test_for_note!(
145 impl_from_file_is_not_todo,
146 from_file_is_not_todo,
147 $impl_note
148 );
149 };
150 }
151
152 pub(crate) use impl_all_tests_is_todo;
153}