Skip to main content

basalt_core/
obsidian.rs

1//! This module provides functionality operating with Obsidian. It lets you read and manipulate
2//! Obsidian's configuration, vaults, and notes.
3//!
4//! Currently supports reading vaults and notes within the vault.
5//!
6//! # Example
7//!
8//! ```
9//! use basalt_core::obsidian::{ObsidianConfig, Error, Vault};
10//!
11//! let config = ObsidianConfig::from([
12//!   ("Obsidian", Vault::default()),
13//!   ("My Vault", Vault::default()),
14//! ]);
15//! ```
16use std::{io, path::PathBuf, result};
17
18pub mod config;
19pub mod directory;
20pub mod note;
21pub mod vault;
22mod vault_entry;
23
24pub use config::ObsidianConfig;
25pub use note::Note;
26pub use vault::*;
27pub use vault_entry::FindNote;
28pub use vault_entry::VaultEntry;
29
30/// A [`std::result::Result`] type for fallible operations in [`crate::obsidian`].
31///
32/// For convenience of use and to avoid writing [`Error`] directly.
33/// All fallible operations return [`Error`] as the error variant.
34///
35/// # Examples
36///
37/// ```
38/// use std::path::Path;
39/// use basalt_core::obsidian;
40///
41/// let config_result = obsidian::config::load_from(Path::new("./nonexistent"));
42/// assert_eq!(config_result.is_err(), true);
43/// ```
44pub type Result<T> = result::Result<T, Error>;
45
46/// Error type for fallible operations in this [`crate`].
47///
48/// Implements [`std::error::Error`] via [thiserror](https://docs.rs/thiserror).
49#[derive(thiserror::Error, Debug)]
50pub enum Error {
51    /// Expected resource behind a path was not found.
52    #[error("Path not found: {0}")]
53    PathNotFound(String),
54
55    /// Failed to extract a valid name from the path.
56    #[error("Invalid path name: {0}")]
57    InvalidPathName(PathBuf),
58
59    /// Filename was empty
60    #[error("Empty filename for path: {0}")]
61    EmptyFileName(PathBuf),
62
63    /// JSON (de)serialization error, from [`serde_json::Error`].
64    #[error("JSON (de)serialization error: {0}")]
65    Json(#[from] serde_json::Error),
66
67    /// I/O error, from [`std::io::Error`].
68    #[error("I/O error: {0}")]
69    Io(#[from] io::Error),
70
71    /// Exceeded maximum attempts while searching for an available note name.
72    ///
73    /// This occurs when creating a note with a name that already exists, and all
74    /// numbered variants (e.g., "Name 1", "Name 2", ..., "Name 999") also exist.
75    #[error("Failed to find available name for '{name}' after {max_attempts} attempts")]
76    MaxAttemptsExceeded {
77        /// The base name that was attempted
78        name: String,
79        /// The maximum number of attempts made
80        max_attempts: usize,
81    },
82}