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//! println!("Tags: {:?}", note_hashmap.tags().unwrap());
38//!
39//! // Parse single file with custom struct
40//! #[derive(Clone, Deserialize)]
41//! struct NoteProperties {
42//!     created: String,
43//!     tags: Vec<String>,
44//!     priority: u8,
45//! }
46//!
47//! let note_with_serde: NoteInMemory<NoteProperties> = NoteInMemory::from_file("note.md").unwrap();
48//! ```
49//!
50//! ### Vault Analysis
51//! ```no_run
52//! use obsidian_parser::prelude::*;
53//!
54//! // Load entire vault
55//! let options = VaultOptions::new("/path/to/vault");
56//! let vault: VaultInMemory = VaultBuilder::new(&options)
57//!     .into_iter()
58//!     .filter_map(Result::ok)
59//!     .build_vault(&options);
60//!
61//! // Check for duplicate note names
62//! if !vault.have_duplicates_notes_by_name() {
63//!     eprintln!("Duplicate note names detected!");
64//! }
65//!
66//! // Access parsed notes
67//! for note in vault.notes() {
68//!   println!("Note: {:?}", note);
69//! }
70//! ```
71//!
72//! ### Graph Analysis (requires [`petgraph`](https://docs.rs/petgraph/latest/petgraph) feature)
73//! ```no_run
74//! #[cfg(feature = "petgraph")]
75//! {
76//!     use obsidian_parser::prelude::*;
77//!     use petgraph::dot::{Dot, Config};
78//!
79//!     let options = VaultOptions::new("/path/to/vault");
80//!     let vault: VaultInMemory = VaultBuilder::new(&options)
81//!         .into_iter()
82//!         .filter_map(Result::ok)
83//!         .build_vault(&options);
84//!
85//!     let graph = vault.get_digraph().unwrap();
86//!     
87//!     // Export to Graphviz format
88//!     println!("{:?}", Dot::with_config(&graph, &[Config::EdgeNoLabel]));
89//!     
90//!     // Find most connected note
91//!     let most_connected = graph.node_indices()
92//!         .max_by_key(|n| graph.edges(*n).count())
93//!         .unwrap();
94//!     println!("Knowledge hub: {:?}", graph[most_connected]);
95//! }
96//! ```
97//! ## Performance
98//! Optimized for large vaults:
99//! - 🚀 1000 files parsed in 2.6 ms (avg)
100//! - 💾 Peak memory: 900KB per 1000 notes
101//!
102//! Parallel processing via Rayon (enable `rayon` feature)
103
104#![warn(missing_docs)]
105#![warn(clippy::pedantic)]
106#![warn(clippy::undocumented_unsafe_blocks)]
107#![warn(clippy::cargo)]
108#![warn(clippy::nursery)]
109#![warn(clippy::perf)]
110#![warn(clippy::unwrap_used)]
111#![warn(clippy::panic)]
112#![warn(clippy::needless_pass_by_value)]
113#![warn(clippy::unreadable_literal)]
114#![warn(clippy::missing_const_for_fn)]
115#![warn(clippy::as_conversions)]
116#![allow(clippy::missing_errors_doc)]
117#![cfg_attr(docsrs, feature(doc_cfg))]
118
119pub mod note;
120pub mod prelude;
121pub mod vault;
122
123#[cfg(test)]
124pub(crate) mod test_utils;