obsidian_parser/
lib.rs

1//! `obsidian-parser` - Blazingly fast Rust library for parsing and analyzing [Obsidian](https://obsidian.md) vaults
2//!
3//! Provides idiomatic APIs for:
4//! - Parsing individual Obsidian notes with frontmatter properties
5//! - Analyzing entire vaults as knowledge graphs
6//! - Extracting semantic relationships between notes
7//!
8//! ## Key Features
9//! * ⚡ **High Performance**: Parses 1000+ notes in under 3ms
10//! * 🧠 **Knowledge Graphs**: Built-in integration with [`petgraph`](https://docs.rs/petgraph/latest/petgraph) for advanced analysis
11//! * 🧩 **Flexible API**: Supports both in-memory and on-disk note representations
12//! * 🔍 **Frontmatter Parsing**: Extract YAML properties with [`serde`](https://docs.rs/serde/latest/serde) compatibility
13//! * 🌐 **Link Analysis**: Identify connections between notes
14//! * 👾 **WebAssembly Support**: Add `obsidian-parser` to your Obsidian plugins
15//!
16//! ## Usage
17//! Add to `Cargo.toml`:
18//! ```toml
19//! [dependencies]
20//! obsidian-parser = { version = "0.9", features = ["petgraph", "rayon", "digest"] }
21//! ```
22//!
23//! ## Examples
24//!
25//! ### Basic Parsing
26//! ```no_run
27//! use obsidian_parser::prelude::*;
28//! use serde::Deserialize;
29//!
30//! // Parse single file with `HashMap`
31//! let note_hashmap = NoteInMemory::from_file_default("note.md").unwrap();
32//!
33//! assert!(!note_hashmap.is_todo().unwrap());
34//!
35//! println!("Content: {}", note_hashmap.content().unwrap());
36//! println!("Properties: {:#?}", note_hashmap.properties().unwrap().unwrap());
37//!
38//! // Parse single file with custom struct
39//! #[derive(Clone, Deserialize)]
40//! struct NoteProperties {
41//!     created: String,
42//!     tags: Vec<String>,
43//!     priority: u8,
44//! }
45//!
46//! let note_with_serde: NoteInMemory<NoteProperties> = NoteInMemory::from_file("note.md").unwrap();
47//! ```
48//!
49//! ### Vault Analysis
50//! ```no_run
51//! use obsidian_parser::prelude::*;
52//!
53//! // Load entire vault
54//! let options = VaultOptions::new("/path/to/vault");
55//! let vault: VaultInMemory = VaultBuilder::new(&options)
56//!     .into_iter()
57//!     .filter_map(Result::ok)
58//!     .build_vault(&options);
59//!
60//! // Check for duplicate note names
61//! if !vault.have_duplicates_notes_by_name() {
62//!     eprintln!("Duplicate note names detected!");
63//! }
64//!
65//! // Access parsed notes
66//! for note in vault.notes() {
67//!   println!("Note: {:?}", note);
68//! }
69//! ```
70//!
71//! ### Graph Analysis (requires [`petgraph`](https://docs.rs/petgraph/latest/petgraph) feature)
72//! ```no_run
73//! #[cfg(feature = "petgraph")]
74//! {
75//!     use obsidian_parser::prelude::*;
76//!     use petgraph::dot::{Dot, Config};
77//!
78//!     let options = VaultOptions::new("/path/to/vault");
79//!     let vault: VaultInMemory = VaultBuilder::new(&options)
80//!         .into_iter()
81//!         .filter_map(Result::ok)
82//!         .build_vault(&options);
83//!
84//!     let graph = vault.get_digraph().unwrap();
85//!     
86//!     // Export to Graphviz format
87//!     println!("{:?}", Dot::with_config(&graph, &[Config::EdgeNoLabel]));
88//!     
89//!     // Find most connected note
90//!     let most_connected = graph.node_indices()
91//!         .max_by_key(|n| graph.edges(*n).count())
92//!         .unwrap();
93//!     println!("Knowledge hub: {:?}", graph[most_connected]);
94//! }
95//! ```
96//! ## Performance
97//! Optimized for large vaults:
98//! - 🚀 1000 files parsed in 2.6 ms (avg)
99//! - 💾 Peak memory: 900KB per 1000 notes
100//!
101//! Parallel processing via Rayon (enable `rayon` feature)
102
103#![warn(missing_docs)]
104#![warn(clippy::pedantic)]
105#![warn(clippy::undocumented_unsafe_blocks)]
106#![warn(clippy::cargo)]
107#![warn(clippy::nursery)]
108#![warn(clippy::perf)]
109#![warn(clippy::unwrap_used)]
110#![warn(clippy::panic)]
111#![warn(clippy::needless_pass_by_value)]
112#![warn(clippy::unreadable_literal)]
113#![warn(clippy::missing_const_for_fn)]
114#![warn(clippy::as_conversions)]
115#![allow(clippy::missing_errors_doc)]
116#![cfg_attr(docsrs, feature(doc_cfg))]
117
118pub mod note;
119pub mod prelude;
120pub mod vault;
121
122#[cfg(test)]
123pub(crate) mod test_utils;