beads_rs/core/
error.rs

1//! Core capability errors (parsing, validation, CRDT invariants).
2//!
3//! These are bounded and stable: core errors represent domain/refusal states,
4//! not library implementation details.
5
6use thiserror::Error;
7
8use crate::error::{Effect, Transience};
9
10/// Invalid ID or content identifier.
11#[derive(Debug, Error, Clone)]
12#[non_exhaustive]
13pub enum InvalidId {
14    #[error("bead id `{raw}` is invalid: {reason}")]
15    Bead { raw: String, reason: String },
16    #[error("actor id `{raw}` is invalid: {reason}")]
17    Actor { raw: String, reason: String },
18    #[error("note id `{raw}` is invalid: {reason}")]
19    Note { raw: String, reason: String },
20    #[error("branch name `{raw}` is invalid: {reason}")]
21    Branch { raw: String, reason: String },
22    #[error("content hash `{raw}` is invalid: {reason}")]
23    ContentHash { raw: String, reason: String },
24}
25
26/// Invalid label string.
27#[derive(Debug, Error, Clone)]
28#[error("label `{raw}` is invalid: {reason}")]
29pub struct InvalidLabel {
30    pub raw: String,
31    pub reason: String,
32}
33
34/// Generic range violation.
35#[derive(Debug, Error, Clone)]
36#[error("{field} value {value} out of range {min}..={max}")]
37pub struct RangeError {
38    pub field: &'static str,
39    pub value: u8,
40    pub min: u8,
41    pub max: u8,
42}
43
44/// ID collision between independently-created beads.
45#[derive(Debug, Error, Clone)]
46#[error("bead id collision: {id} has conflicting creation stamps")]
47pub struct CollisionError {
48    pub id: String,
49}
50
51/// Invalid dependency edge.
52#[derive(Debug, Error, Clone)]
53#[error("invalid dependency: {reason}")]
54pub struct InvalidDependency {
55    pub reason: String,
56}
57
58/// Invalid dependency kind string.
59#[derive(Debug, Error, Clone)]
60#[error("dependency kind `{raw}` is invalid")]
61pub struct InvalidDepKind {
62    pub raw: String,
63}
64
65/// Canonical error enum for core capability.
66#[derive(Debug, Error, Clone)]
67#[non_exhaustive]
68pub enum CoreError {
69    #[error(transparent)]
70    InvalidId(#[from] InvalidId),
71    #[error(transparent)]
72    InvalidLabel(#[from] InvalidLabel),
73    #[error(transparent)]
74    Range(#[from] RangeError),
75    #[error(transparent)]
76    Collision(#[from] CollisionError),
77    #[error(transparent)]
78    InvalidDependency(#[from] InvalidDependency),
79    #[error(transparent)]
80    InvalidDepKind(#[from] InvalidDepKind),
81}
82
83impl CoreError {
84    pub fn transience(&self) -> Transience {
85        // Core errors are pure domain/input failures.
86        Transience::Permanent
87    }
88
89    pub fn effect(&self) -> Effect {
90        Effect::None
91    }
92}