obsidian_parser/note/
note_aliases.rs

1//! Impl trait [`NoteAliases`]
2
3use super::{DefaultProperties, Note};
4
5const ALIASES_FIELD_NAME: &str = "aliases";
6
7/// Getting aliases from note
8///
9/// # Example
10///
11/// ```
12/// use obsidian_parser::prelude::*;
13///
14/// let raw_text = "---\ntags:\n- todo\n---\nSameData";
15/// let note = NoteInMemory::from_string(raw_text).unwrap();
16///
17/// let aliases = note.aliases().unwrap();
18/// assert!(aliases.is_empty());
19/// ```
20pub trait NoteAliases: Note {
21    /// Get aliases from note
22    ///
23    /// # Example
24    ///
25    /// ```
26    /// use obsidian_parser::prelude::*;
27    ///
28    /// let raw_text = "---\ntags:\n- todo\n---\nSameData";
29    /// let note = NoteInMemory::from_string(raw_text).unwrap();
30    ///
31    /// let aliases = note.aliases().unwrap();
32    /// assert!(aliases.is_empty());
33    /// ```
34    fn aliases(&self) -> Result<Vec<String>, Self::Error>;
35
36    /// Get count aliases from note
37    ///
38    /// # Example
39    ///
40    /// ```
41    /// use obsidian_parser::prelude::*;
42    ///
43    /// let raw_text = "---\naliases:\n- my_alias\n---\nSameData";
44    /// let note = NoteInMemory::from_string(raw_text).unwrap();
45    ///
46    /// let count_aliases = note.count_aliases().unwrap();
47    /// assert_eq!(count_aliases, 1);
48    /// ```
49    #[inline]
50    fn count_aliases(&self) -> Result<usize, Self::Error> {
51        let aliases = self.aliases()?;
52        Ok(aliases.len())
53    }
54
55    /// Have aliases in note?
56    ///
57    /// # Example
58    ///
59    /// ```
60    /// use obsidian_parser::prelude::*;
61    ///
62    /// let raw_text = "---\naliases:\n- my_alias\n---\nSameData";
63    /// let note = NoteInMemory::from_string(raw_text).unwrap();
64    ///
65    /// let have_aliases = note.have_aliases().unwrap();
66    /// assert!(have_aliases);
67    /// ```
68    #[inline]
69    fn have_aliases(&self) -> Result<bool, Self::Error> {
70        let aliases = self.count_aliases()?;
71        Ok(aliases != 0)
72    }
73}
74
75impl<N> NoteAliases for N
76where
77    N: Note<Properties = DefaultProperties>,
78    N::Error: From<serde_yml::Error>,
79{
80    #[cfg_attr(feature = "tracing", tracing::instrument(skip(self), ret, fields(path = format!("{:?}", self.path()))))]
81    fn aliases(&self) -> Result<Vec<String>, Self::Error> {
82        let properties = self.properties()?.unwrap_or_default();
83
84        match properties.get(ALIASES_FIELD_NAME) {
85            Some(value) => {
86                let aliases = serde_yml::from_value(value.clone())?;
87
88                Ok(aliases)
89            }
90            None => Ok(Vec::default()),
91        }
92    }
93}
94
95#[cfg(test)]
96pub(crate) mod tests {
97    use super::*;
98    use crate::note::{NoteFromFile, NoteFromReader, NoteFromString};
99    use std::io::{Cursor, Write};
100    use tempfile::NamedTempFile;
101
102    const TEST_DATA_HAVE_ALIASES: &str = "---\naliases:\n- my_alias\n---\nSameData";
103    const TEST_DATA_NOT_HAVE_ALIASES: &str = "---\ntags:\n- todo\n---\nSameData";
104
105    fn have_aliases<N>(note: &N) -> Result<(), N::Error>
106    where
107        N: Note<Properties = DefaultProperties>,
108        N::Error: From<serde_yml::Error>,
109    {
110        let aliases = note.aliases()?;
111
112        assert_eq!(aliases, vec!["my_alias".to_string()]);
113        Ok(())
114    }
115
116    fn have_not_aliases<N>(note: &N) -> Result<(), N::Error>
117    where
118        N: Note<Properties = DefaultProperties>,
119        N::Error: From<serde_yml::Error>,
120    {
121        let aliases = note.aliases()?;
122
123        assert!(aliases.is_empty());
124        Ok(())
125    }
126
127    pub(crate) fn from_string_have_aliases<N>() -> Result<(), N::Error>
128    where
129        N: NoteFromString<Properties = DefaultProperties>,
130        N::Error: From<serde_yml::Error>,
131    {
132        let note = N::from_string(TEST_DATA_HAVE_ALIASES)?;
133        have_aliases(&note)
134    }
135
136    pub(crate) fn from_string_have_not_aliases<N>() -> Result<(), N::Error>
137    where
138        N: NoteFromString<Properties = DefaultProperties>,
139        N::Error: From<serde_yml::Error>,
140    {
141        let note = N::from_string(TEST_DATA_NOT_HAVE_ALIASES)?;
142        have_not_aliases(&note)
143    }
144
145    pub(crate) fn from_reader_have_aliases<N>() -> Result<(), N::Error>
146    where
147        N: NoteFromReader<Properties = DefaultProperties>,
148        N::Error: From<serde_yml::Error> + From<std::io::Error>,
149    {
150        let note = N::from_reader(&mut Cursor::new(TEST_DATA_HAVE_ALIASES))?;
151        have_aliases(&note)
152    }
153
154    pub(crate) fn from_reader_have_not_aliases<N>() -> Result<(), N::Error>
155    where
156        N: NoteFromReader<Properties = DefaultProperties>,
157        N::Error: From<serde_yml::Error> + From<std::io::Error>,
158    {
159        let note = N::from_reader(&mut Cursor::new(TEST_DATA_NOT_HAVE_ALIASES))?;
160        have_not_aliases(&note)
161    }
162
163    pub(crate) fn from_file_have_aliases<N>() -> Result<(), N::Error>
164    where
165        N: NoteFromFile<Properties = DefaultProperties>,
166        N::Error: From<serde_yml::Error> + From<std::io::Error>,
167    {
168        let mut file = NamedTempFile::new().unwrap();
169        file.write_all(TEST_DATA_HAVE_ALIASES.as_bytes()).unwrap();
170
171        let note = N::from_file(file.path())?;
172        have_aliases(&note)
173    }
174
175    pub(crate) fn from_file_have_not_aliases<N>() -> Result<(), N::Error>
176    where
177        N: NoteFromFile<Properties = DefaultProperties>,
178        N::Error: From<serde_yml::Error> + From<std::io::Error>,
179    {
180        let mut file = NamedTempFile::new().unwrap();
181        file.write_all(TEST_DATA_NOT_HAVE_ALIASES.as_bytes())
182            .unwrap();
183
184        let note = N::from_file(file.path())?;
185        have_not_aliases(&note)
186    }
187
188    macro_rules! impl_all_tests_aliases {
189        ($impl_note:path) => {
190            #[allow(unused_imports)]
191            use $crate::note::note_aliases::tests::*;
192
193            impl_test_for_note!(
194                impl_from_string_have_aliases,
195                from_string_have_aliases,
196                $impl_note
197            );
198            impl_test_for_note!(
199                impl_from_string_have_not_aliases,
200                from_string_have_not_aliases,
201                $impl_note
202            );
203
204            impl_test_for_note!(
205                impl_from_reader_have_aliases,
206                from_reader_have_aliases,
207                $impl_note
208            );
209            impl_test_for_note!(
210                impl_from_reader_have_not_aliases,
211                from_reader_have_not_aliases,
212                $impl_note
213            );
214
215            impl_test_for_note!(
216                impl_from_file_have_aliases,
217                from_file_have_aliases,
218                $impl_note
219            );
220            impl_test_for_note!(
221                impl_from_file_have_not_aliases,
222                from_file_have_not_aliases,
223                $impl_note
224            );
225        };
226    }
227
228    pub(crate) use impl_all_tests_aliases;
229}