obsidian_parser/vault/
mod.rs

1//! Obsidian vault parsing and analysis
2//!
3//! Provides functionality for working with entire Obsidian vaults (collections of notes)
4//!
5//! # Performance Recommendations
6//! **Prefer [`NoteOnDisk`] over [`NoteInMemory`] for large vaults** - it uses significantly less memory
7//! by reading files on-demand rather than loading everything into memory upfront.
8
9pub mod error;
10pub mod vault_duplicates;
11pub mod vault_open;
12
13#[cfg(feature = "petgraph")]
14#[cfg_attr(docsrs, doc(cfg(feature = "petgraph")))]
15pub mod vault_petgraph;
16
17#[cfg(test)]
18mod vault_test;
19
20use crate::note::DefaultProperties;
21use crate::note::Note;
22use crate::prelude::{NoteInMemory, NoteOnDisk, NoteOnceCell, NoteOnceLock};
23use std::path::{Path, PathBuf};
24
25/// Vault, but used [`NoteOnDisk`]
26pub type VaultOnDisk<T = DefaultProperties> = Vault<NoteOnDisk<T>>;
27
28/// Vault, but used [`NoteOnceCell`]
29pub type VaultOnceCell<T = DefaultProperties> = Vault<NoteOnceCell<T>>;
30
31/// Vault, but used [`NoteOnceLock`]
32pub type VaultOnceLock<T = DefaultProperties> = Vault<NoteOnceLock<T>>;
33
34/// Vault, but used [`NoteInMemory`]
35pub type VaultInMemory<T = DefaultProperties> = Vault<NoteInMemory<T>>;
36
37/// Represents an entire Obsidian vault
38///
39/// Contains all parsed notes and metadata about the vault. Uses [`NoteOnDisk`] by default
40/// which is optimized for memory efficiency in large vaults.
41#[derive(Debug, Default, PartialEq, Eq, Clone)]
42pub struct Vault<N = NoteInMemory>
43where
44    N: Note,
45{
46    /// All notes in the vault
47    notes: Vec<N>,
48
49    /// Path to vault root directory
50    path: PathBuf,
51}
52
53impl<N> Vault<N>
54where
55    N: Note,
56{
57    /// Get notes
58    #[must_use]
59    #[inline]
60    pub const fn notes(&self) -> &Vec<N> {
61        &self.notes
62    }
63
64    /// Get mutables notes
65    #[must_use]
66    #[inline]
67    pub const fn mut_notes(&mut self) -> &mut Vec<N> {
68        &mut self.notes
69    }
70
71    /// Get count in notes from vault
72    #[must_use]
73    #[inline]
74    pub const fn count_notes(&self) -> usize {
75        self.notes().len()
76    }
77
78    /// Get path to vault
79    #[must_use]
80    #[inline]
81    pub fn path(&self) -> &Path {
82        &self.path
83    }
84}
85
86#[cfg(test)]
87mod tests {
88    use super::*;
89    use crate::{
90        prelude::{IteratorVaultBuilder, VaultBuilder, VaultOptions},
91        vault::vault_test::create_files_for_vault,
92    };
93
94    #[cfg_attr(feature = "tracing", tracing_test::traced_test)]
95    #[test]
96    fn notes() {
97        let (path, files) = create_files_for_vault().unwrap();
98
99        let options = VaultOptions::new(&path);
100        let vault: VaultInMemory = VaultBuilder::new(&options)
101            .include_hidden(true)
102            .into_iter()
103            .map(|file| file.unwrap())
104            .build_vault(&options);
105
106        assert_eq!(vault.notes().len(), files.len());
107    }
108
109    #[cfg_attr(feature = "tracing", tracing_test::traced_test)]
110    #[test]
111    fn count_notes() {
112        let (path, files) = create_files_for_vault().unwrap();
113
114        let options = VaultOptions::new(&path);
115        let vault: VaultInMemory = VaultBuilder::new(&options)
116            .include_hidden(true)
117            .into_iter()
118            .map(|file| file.unwrap())
119            .build_vault(&options);
120
121        assert_eq!(vault.count_notes(), files.len());
122    }
123
124    #[cfg_attr(feature = "tracing", tracing_test::traced_test)]
125    #[test]
126    fn path() {
127        let (path, _) = create_files_for_vault().unwrap();
128
129        let options = VaultOptions::new(&path);
130        let vault: VaultInMemory = VaultBuilder::new(&options)
131            .include_hidden(true)
132            .into_iter()
133            .map(|file| file.unwrap())
134            .build_vault(&options);
135
136        assert_eq!(vault.path(), path.path());
137    }
138}