mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-19 00:03:30 +00:00
136 lines
4.2 KiB
Rust
136 lines
4.2 KiB
Rust
use std::path::PathBuf;
|
|
|
|
use toml::de::Error as TomlDeError;
|
|
use toml::ser::Error as TomlSerError;
|
|
|
|
use crate::{EnvironmentId, EnvironmentRevision, EnvironmentRevisionParseError};
|
|
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum EnvironmentValidationError {
|
|
#[error("environment id {value:?} must match [a-z0-9][a-z0-9-]{{0,62}}")]
|
|
InvalidEnvironmentId { value: String },
|
|
#[error("environment settings are invalid: {}", .errors.join("; "))]
|
|
InvalidSettings { errors: Vec<String> },
|
|
#[error("failed to read Dockerfile referenced by environment at {path:?}")]
|
|
DockerfileRead {
|
|
path: PathBuf,
|
|
#[source]
|
|
source: std::io::Error,
|
|
},
|
|
#[error(
|
|
"Dockerfile path sources are not supported for stored environments; use inline Dockerfile content"
|
|
)]
|
|
DockerfilePathUnsupported,
|
|
}
|
|
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum EnvironmentStoreError {
|
|
#[error("environment not found: {id}")]
|
|
NotFound { id: EnvironmentId },
|
|
#[error("environment already exists: {id}")]
|
|
AlreadyExists { id: EnvironmentId },
|
|
#[error("environment revision is stale for {id}: expected {expected}, actual {actual}")]
|
|
StaleRevision {
|
|
id: EnvironmentId,
|
|
expected: EnvironmentRevision,
|
|
actual: EnvironmentRevision,
|
|
},
|
|
#[error("environment is reserved and cannot be modified: {id}")]
|
|
Reserved { id: EnvironmentId },
|
|
#[error("environment validation failed: {source}")]
|
|
Validation {
|
|
#[from]
|
|
source: EnvironmentValidationError,
|
|
},
|
|
#[error("invalid environment filename at {path:?}")]
|
|
InvalidFilename { path: PathBuf, reason: String },
|
|
#[error("failed to parse environment TOML at {path:?}")]
|
|
Parse {
|
|
path: PathBuf,
|
|
#[source]
|
|
source: TomlDeError,
|
|
},
|
|
#[error("invalid persisted environment revision for {id}")]
|
|
InvalidRevision {
|
|
id: EnvironmentId,
|
|
#[source]
|
|
source: EnvironmentRevisionParseError,
|
|
},
|
|
#[error("environment TOML at {path:?} is not UTF-8")]
|
|
InvalidUtf8 {
|
|
path: PathBuf,
|
|
#[source]
|
|
source: std::str::Utf8Error,
|
|
},
|
|
#[error("failed to serialize environment TOML")]
|
|
Serialize {
|
|
#[from]
|
|
source: TomlSerError,
|
|
},
|
|
#[error("I/O error at {path:?}")]
|
|
Io {
|
|
path: PathBuf,
|
|
#[source]
|
|
source: std::io::Error,
|
|
},
|
|
#[error("failed to encode environment JSON for {field}")]
|
|
JsonEncode {
|
|
field: &'static str,
|
|
#[source]
|
|
source: serde_json::Error,
|
|
},
|
|
#[error("failed to decode environment JSON for {field}")]
|
|
JsonDecode {
|
|
field: &'static str,
|
|
#[source]
|
|
source: serde_json::Error,
|
|
},
|
|
#[error("database error")]
|
|
Db {
|
|
#[from]
|
|
source: sqlx::Error,
|
|
},
|
|
#[error("environment row count {count} exceeds SQLite integer range")]
|
|
RowCountOverflow { count: usize },
|
|
}
|
|
|
|
impl EnvironmentStoreError {
|
|
pub(crate) fn io(path: impl Into<PathBuf>, source: std::io::Error) -> Self {
|
|
Self::Io {
|
|
path: path.into(),
|
|
source,
|
|
}
|
|
}
|
|
|
|
pub(crate) fn parse(path: impl Into<PathBuf>, source: TomlDeError) -> Self {
|
|
Self::Parse {
|
|
path: path.into(),
|
|
source,
|
|
}
|
|
}
|
|
|
|
pub(crate) fn invalid_utf8(path: impl Into<PathBuf>, source: std::str::Utf8Error) -> Self {
|
|
Self::InvalidUtf8 {
|
|
path: path.into(),
|
|
source,
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn kind(&self) -> &'static str {
|
|
match self {
|
|
Self::NotFound { .. } => "not_found",
|
|
Self::AlreadyExists { .. } => "already_exists",
|
|
Self::StaleRevision { .. } => "stale_revision",
|
|
Self::Reserved { .. } => "reserved",
|
|
Self::Validation { .. } => "validation",
|
|
Self::InvalidFilename { .. } => "invalid_filename",
|
|
Self::Parse { .. } | Self::InvalidUtf8 { .. } | Self::InvalidRevision { .. } => "parse",
|
|
Self::Serialize { .. } => "serialize",
|
|
Self::JsonEncode { .. } | Self::JsonDecode { .. } => "json",
|
|
Self::Db { .. } => "db",
|
|
Self::RowCountOverflow { .. } => "row_count_overflow",
|
|
Self::Io { .. } => "io",
|
|
}
|
|
}
|
|
}
|