use std::path::PathBuf;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
#[error("reading {path}: {source}")]
Io {
path: PathBuf,
#[source]
source: std::io::Error,
},
#[error("{path}: {source}")]
Config {
path: PathBuf,
#[source]
source: toml::de::Error,
},
#[error(
"externals.relations: \"{from}\" (under external \"{external}\") names no element in the surveyed model"
)]
UnknownRelationSource { external: String, from: String },
#[error(
"externals: id \"{id}\" is not an identifier (letters, digits and _, not starting with a digit, not a keyword)"
)]
InvalidExternalId { id: String },
#[error(
"externals: \"{id}\" declares kind \"{kind}\", which the survey generates ({surveyed}); give an external its own kind"
)]
ExternalKindIsSurveyed {
id: String,
kind: String,
surveyed: String,
},
#[error("element ids \"{first}\" and \"{second}\" both become the LikeC4 id \"{id}\"")]
DuplicateId {
id: String,
first: String,
second: String,
},
#[error("theme: \"{kind}\" is not an element kind of the surveyed model (have {have})")]
UnknownThemeKind { kind: String, have: String },
#[error("{path}: {entry} is not a top-level entry asbuilt reads (tables: {known})")]
UnknownTopLevel {
path: PathBuf,
entry: String,
known: String,
},
#[error("no supported stack detected at {root}")]
NoFrontend { root: PathBuf },
#[error("{frontend} front-end: {source}")]
Frontend {
frontend: String,
#[source]
source: Box<dyn std::error::Error + Send + Sync + 'static>,
},
}
pub type Result<T> = std::result::Result<T, Error>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn an_unknown_relation_source_names_the_external_and_the_from() {
let msg = Error::UnknownRelationSource {
external: "node_driver".into(),
from: "playwright_rs.nope".into(),
}
.to_string();
assert!(msg.contains("node_driver"), "{msg}");
assert!(msg.contains("playwright_rs.nope"), "{msg}");
}
#[test]
fn a_duplicate_id_names_both_originals_and_the_collision() {
let msg = Error::DuplicateId {
id: "foo_bar".into(),
first: "foo-bar".into(),
second: "foo_bar".into(),
}
.to_string();
assert!(
msg.contains("\"foo-bar\"") && msg.contains("\"foo_bar\""),
"{msg}"
);
}
}