Files
rota/src-tauri/src/errors.rs

97 lines
2.7 KiB
Rust

use std::io;
use log::Level;
use serde::Serialize;
use thiserror::Error;
#[derive(Error, Debug, Serialize)]
#[serde(tag = "kind", content = "details")]
pub enum SearchError {
#[error("another thread found a solution")]
SolutionFound,
#[error("time limit exceeded")]
Timeout,
#[error("schedule is already manually filled")]
ScheduleFull,
#[error("user configuration is invalid")]
Config(String),
#[error("no solution found")]
NoSolutionFound,
}
impl SearchError {
pub fn log_level(&self) -> Level {
match self {
SearchError::SolutionFound | SearchError::ScheduleFull => Level::Info,
SearchError::NoSolutionFound => Level::Warn,
SearchError::Timeout | SearchError::Config(_) => Level::Error,
}
}
}
impl From<anyhow::Error> for SearchError {
fn from(err: anyhow::Error) -> Self {
SearchError::Config(err.to_string())
}
}
#[derive(Error, Debug)]
pub enum ExportError {
#[error("no schedule has been generated yet")]
NotGenerated,
#[error("path not found: {0}")]
InvalidPath(#[from] io::Error),
#[error("docx packaging error: {0}")]
Packaging(String),
#[error("failed to open doc: {0}")]
OpenFailed(String),
}
#[derive(Error, Debug, Serialize)]
#[serde(tag = "kind", content = "details")]
pub enum SwapError {
#[error("no schedule has been generated yet")]
NotGenerated,
#[error("invalid shift position: {0}")]
InvalidPosition(String),
#[error("slot has no assigned resident")]
SlotEmpty,
#[error("both slots belong to the same resident")]
SameResident,
#[error("resident not found in config")]
ResidentNotFound,
#[error("resident cannot take the target slot: negative shift or disallowed type")]
ResidentCannotTakeSlot,
#[error("swap violates same-day or toxic pair constraint")]
SameDayOrToxicPair,
#[error("swap creates a consecutive-day constraint violation")]
ConsecutiveDays,
#[error("cannot swap the same slot or slots on the same day")]
SameSlotOrDay,
}
impl Serialize for ExportError {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeStruct;
let mut s = serializer.serialize_struct("ExportError", 2)?;
s.serialize_field(
"kind",
match self {
ExportError::NotGenerated => "NotGenerated",
ExportError::InvalidPath(_) => "InvalidPath",
ExportError::Packaging(_) => "Packaging",
ExportError::OpenFailed(_) => "OpenFailed",
},
)?;
s.serialize_field("details", &self.to_string())?;
s.end()
}
}