obsidian_parser/lib.rs
1//! `obsidian-parser` - Blazingly fast Rust library for parsing and analyzing Obsidian 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//! * π‘οΈ **100% Safe Rust** - Strictly forbids unsafe code (`#![forbid(unsafe_code)]`)
10//! * β‘ **High Performance** - Parses 1000 notes in <3ms
11//! * πΈοΈ **Knowledge Graphs** - Built-in petgraph integration for graph analysis (requires `petgraph` feature)
12//!
13//! ## Usage
14//! Add to `Cargo.toml`:
15//! ```toml
16//! [dependencies]
17//! obsidian-parser = { version = "0.1", features = ["petgraph", "rayon"] }
18//! ```
19//!
20//! ## Examples
21//!
22//! ### Basic Parsing
23//! ```no_run
24//! use obsidian_parser::prelude::*;
25//! use serde::Deserialize;
26//!
27//! // Parse single file with `HashMap`
28//! let note_hashmap = ObFileInMemory::from_file_default("note.md").unwrap();
29//!
30//! println!("Content: {}", note_hashmap.content());
31//! println!("Properties: {:#?}", note_hashmap.properties());
32//!
33//! // Parse single file with custom struct
34//! #[derive(Clone, Default, Deserialize)]
35//! struct NoteProperties {
36//! created: String,
37//! tags: Vec<String>,
38//! priority: u8,
39//! }
40//!
41//! let note_with_serde: ObFileInMemory<NoteProperties> = ObFileInMemory::from_file("note.md").unwrap();
42//! ```
43//!
44//! ### Vault Analysis
45//! ```no_run
46//! use obsidian_parser::prelude::*;
47//!
48//! // Load entire vault
49//! let vault = Vault::open_default("/path/to/vault").unwrap();
50//!
51//! // Check for duplicate note names
52//! if !vault.has_unique_filenames() {
53//! eprintln!("Duplicate note names detected!");
54//! }
55//! ```
56//!
57//! ### Graph Analysis (requires `petgraph` feature)
58//! ```no_run
59//! #[cfg(feature = "petgraph")]
60//! {
61//! use obsidian_parser::prelude::*;
62//! use petgraph::dot::{Dot, Config};
63//!
64//! let vault = Vault::open_default("/path/to/vault").unwrap();
65//! let graph = vault.get_digraph();
66//!
67//! // Export to Graphviz format
68//! println!("{:?}", Dot::with_config(&graph, &[Config::EdgeNoLabel]));
69//!
70//! // Find most connected note
71//! let most_connected = graph.node_indices()
72//! .max_by_key(|n| graph.edges(*n).count())
73//! .unwrap();
74//! println!("Knowledge hub: {}", graph[most_connected]);
75//! }
76//! ```
77//!
78//! ## Performance
79//! Optimized for large vaults:
80//! - π 1000 files parsed in 2.7ms (avg)
81//! - πΎ Peak memory: 900KB per 1000 notes
82//!
83//! Parallel processing via Rayon (enable `rayon` feature)
84//!
85//! ## Graph Features
86//! When `petgraph` feature is enabled:
87//! - Build directed/undirected knowledge graphs
88//! - Analyze note connectivity
89//! - Detect knowledge clusters
90//! - Calculate centrality metrics
91//!
92//! Graph nodes use note names, edges represent links (`[[...]]`).
93
94#![forbid(unsafe_code)]
95#![warn(clippy::pedantic)]
96#![warn(clippy::cargo)]
97#![warn(clippy::nursery)]
98#![warn(clippy::perf)]
99#![warn(clippy::unwrap_used)]
100#![warn(clippy::panic)]
101#![warn(clippy::needless_pass_by_value)]
102#![warn(clippy::unreadable_literal)]
103#![warn(clippy::missing_const_for_fn)]
104#![warn(clippy::as_conversions)]
105
106pub mod error;
107pub mod obfile;
108pub mod vault;
109
110#[cfg(test)]
111pub(crate) mod test_utils;
112
113pub mod prelude {
114 pub use crate::obfile::obfile_in_memory::ObFileInMemory;
115 pub use crate::obfile::obfile_on_disk::ObFileOnDisk;
116 pub use crate::obfile::{ObFile, ObFileDefault};
117 pub use crate::vault::Vault;
118}