use std::fmt;
use std::ops::Deref;
use thiserror::Error;
pub(super) const SUPPORTED_META_SCHEMA: &str = "http://json-schema.org/draft-07/schema#";
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SchemaKind {
Metadata,
Entries,
}
impl fmt::Display for SchemaKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SchemaKind::Metadata => f.write_str("metadata_schema"),
SchemaKind::Entries => f.write_str("entries_schema"),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Error)]
pub enum RuleViolation {
#[error("a workflow is required by this bucket, but none was selected")]
WorkflowRequired,
#[error("a commit message is required by this workflow, but none was provided")]
MessageRequired,
#[error("package name {name:?} does not match the required handle_pattern {pattern:?}")]
HandleMismatch { name: String, pattern: String },
#[error("package metadata does not satisfy the workflow's metadata_schema: {0}")]
MetadataInvalid(String),
#[error("package entries do not satisfy the workflow's entries_schema: {0}")]
EntriesInvalid(String),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Violations(Vec<RuleViolation>);
impl Violations {
#[must_use]
pub fn from_nonempty(list: Vec<RuleViolation>) -> Option<Self> {
(!list.is_empty()).then_some(Self(list))
}
}
impl Deref for Violations {
type Target = [RuleViolation];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl fmt::Display for Violations {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for violation in self.iter() {
write!(f, "\n - {violation}")?;
}
Ok(())
}
}
impl From<RuleViolation> for Violations {
fn from(violation: RuleViolation) -> Self {
Violations(vec![violation])
}
}
#[derive(Debug, Error)]
pub enum WorkflowValidationError {
#[error("workflow {kind} is not a valid Draft-7 JSON Schema: {reason}")]
InvalidSchema { kind: SchemaKind, reason: String },
#[error("workflow {kind} uses `$ref`, which is not supported")]
UnsupportedRef { kind: SchemaKind },
#[error(
"workflow {kind} declares `$schema`: {value}, which is not supported \
(only the Draft-7 meta-schema {SUPPORTED_META_SCHEMA:?} is supported)"
)]
UnsupportedMetaSchema { kind: SchemaKind, value: String },
#[error("workflow handle_pattern {pattern:?} is not a valid regular expression: {reason}")]
InvalidHandlePattern { pattern: String, reason: String },
#[error("package does not satisfy the workflow:{0}")]
Rejected(Violations),
}
#[derive(Debug, Error)]
pub enum ConfigError {
#[error("Workflow error: {0}")]
Workflow(String),
#[error("Invalid workflows config: {0}")]
InvalidWorkflowsConfig(String),
#[error(transparent)]
Uri(#[from] quilt_uri::UriError),
}