stoa_core/error.rs
1//! Error types for stoa-core.
2//!
3//! Validation errors carry the offending page id + field so callers can
4//! produce actionable diagnostics (see CLI `schema --check`).
5
6use thiserror::Error;
7
8/// Library error for stoa-core. Currently only validation surfaces here;
9/// frontmatter parse failures bubble up as `serde_yaml::Error` directly.
10#[derive(Debug, Error)]
11pub enum Error {
12 /// YAML (de)serialization failure.
13 #[error("yaml error: {0}")]
14 Yaml(#[from] serde_yaml::Error),
15
16 /// One or more validation rules failed against the workspace schema.
17 #[error("validation failed:\n{0}")]
18 Validation(String),
19}
20
21/// Convenience `Result` alias.
22pub type Result<T> = std::result::Result<T, Error>;
23
24/// A single validation failure — produced by [`crate::validate_page`].
25///
26/// Multiple errors are joined for display in [`Error::Validation`]; this
27/// struct exists so callers can render diagnostics in their own format.
28#[derive(Debug, Clone, PartialEq, Eq)]
29pub struct ValidationError {
30 /// Page id (e.g. `ent-redis`) the error applies to.
31 pub page_id: String,
32 /// Field name the rule applies to (e.g. `kind`, `status`, `type`).
33 pub field: String,
34 /// Human-readable explanation, includes the offending value.
35 pub message: String,
36}
37
38impl ValidationError {
39 /// Construct a new [`ValidationError`].
40 pub fn new(
41 page_id: impl Into<String>,
42 field: impl Into<String>,
43 message: impl Into<String>,
44 ) -> Self {
45 Self {
46 page_id: page_id.into(),
47 field: field.into(),
48 message: message.into(),
49 }
50 }
51}
52
53impl std::fmt::Display for ValidationError {
54 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55 write!(f, "page `{}` field `{}`: {}", self.page_id, self.field, self.message)
56 }
57}