kevy_config/error.rs
1//! `ConfigError` — the error type [`crate::Config::load`] /
2//! [`crate::Config::from_toml_str`] / `merge_env` / `merge_cli` return.
3//! Lifted out of `schema.rs` to keep that file under the 500-LOC
4//! house rule; the schema module now stays focused on the data
5//! definitions while this one owns the failure surface.
6
7use std::path::PathBuf;
8
9/// Reasons `Config::load` / `from_toml_str` can fail.
10#[derive(Debug)]
11pub enum ConfigError {
12 /// File could not be opened or read.
13 IoOpen {
14 /// Path that failed to open.
15 path: PathBuf,
16 /// Underlying error message.
17 err: String,
18 },
19 /// Tokenizer / parser error with line + column.
20 Parse {
21 /// 1-based line number in the source.
22 line: usize,
23 /// 1-based column number in the source.
24 col: usize,
25 /// Human-readable error.
26 msg: String,
27 },
28 /// Value passed schema validation but the field rejected it
29 /// (e.g. unknown enum variant, out-of-range integer).
30 Schema {
31 /// 1-based line number where the offending value appeared.
32 line: usize,
33 /// `[section].key` of the rejected setting.
34 field: String,
35 /// Human-readable error.
36 msg: String,
37 },
38}
39
40impl std::fmt::Display for ConfigError {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 match self {
43 Self::IoOpen { path, err } => {
44 write!(f, "kevy-config: cannot read {}: {err}", path.display())
45 }
46 Self::Parse { line, col, msg } => {
47 write!(f, "kevy-config: parse error at line {line} col {col}: {msg}")
48 }
49 Self::Schema { line, field, msg } => {
50 write!(f, "kevy-config: schema error at line {line} on {field}: {msg}")
51 }
52 }
53 }
54}
55
56impl std::error::Error for ConfigError {}