Initial commit

This commit is contained in:
2026-03-25 09:32:02 +01:00
commit 23ce1b7ee2
77 changed files with 21169 additions and 0 deletions

104
brittle-core/src/error.rs Normal file
View File

@@ -0,0 +1,104 @@
use std::path::PathBuf;
use thiserror::Error;
/// Top-level error returned from all public Brittle API methods.
#[derive(Debug, Error)]
pub enum BrittleError {
#[error("{0}")]
Store(#[from] StoreError),
#[error("{0}")]
Validation(#[from] ValidationError),
#[error("{0}")]
BibTeX(#[from] BibtexError),
}
/// Errors from the storage layer.
#[derive(Debug, Error)]
pub enum StoreError {
#[error("{entity_type} not found: {id}")]
NotFound { entity_type: EntityType, id: String },
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
#[error("serialization error: {message}")]
Serialization { message: String },
#[error("deserialization error for {path}: {message}")]
Deserialization { path: PathBuf, message: String },
#[error("git error: {0}")]
Git(#[from] git2::Error),
#[error("repository not found at {path}")]
RepoNotFound { path: PathBuf },
#[error("repository already exists at {path}")]
RepoAlreadyExists { path: PathBuf },
}
/// The kind of entity involved in a not-found error.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EntityType {
Reference,
Library,
Annotation,
Snapshot,
}
impl std::fmt::Display for EntityType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
EntityType::Reference => write!(f, "Reference"),
EntityType::Library => write!(f, "Library"),
EntityType::Annotation => write!(f, "Annotation"),
EntityType::Snapshot => write!(f, "Snapshot"),
}
}
}
/// Business logic validation errors.
#[derive(Debug, Error)]
pub enum ValidationError {
#[error(
"library cycle detected: moving library {library_id} under {parent_id} would create a cycle"
)]
LibraryCycle {
library_id: String,
parent_id: String,
},
#[error("library {id} has children and cannot be deleted; delete or move children first")]
LibraryHasChildren { id: String },
#[error("cite key already exists: {cite_key}")]
DuplicateCiteKey { cite_key: String },
#[error("cite key cannot be empty")]
EmptyCiteKey,
#[error("library name cannot be empty")]
EmptyLibraryName,
#[error("reference {reference_id} has no PDF attached")]
NoPdfAttached { reference_id: String },
#[error("PDF file not found: {path}")]
PdfNotFound { path: PathBuf },
#[error("there are uncommitted changes; create a snapshot or call discard_changes() first")]
UncommittedChanges,
}
/// Errors specific to BibTeX export.
#[derive(Debug, Error)]
pub enum BibtexError {
#[error("reference '{cite_key}' ({entry_type}): missing required field '{field}'")]
MissingRequiredField {
cite_key: String,
entry_type: String,
field: String,
},
}