use castep_cell_fmt::{Cell, CellValue, ToCell, ToCellValue, CResult};
use castep_cell_fmt::parse::FromKeyValue;
use castep_cell_fmt::query::value_as_str;
use castep_cell_fmt::Error;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WriteCheckpoint {
pub action: WriteCheckpointAction,
pub option: Option<WriteCheckpointOption>,
}
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub enum WriteCheckpointAction {
None,
Minimal,
Both,
All,
Full,
}
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub enum WriteCheckpointOption {
Success(WriteCheckpointAction),
Failure(WriteCheckpointAction),
Backup(WriteCheckpointAction),
}
impl Default for WriteCheckpoint {
fn default() -> Self {
Self {
action: WriteCheckpointAction::All, option: None,
}
}
}
impl FromKeyValue for WriteCheckpoint {
const KEY_NAME: &'static str = "WRITE_CHECKPOINT";
fn from_cell_value_kv(value: &CellValue<'_>) -> CResult<Self> {
let s = value_as_str(value)?;
if let Some((option_type, option_value)) = s.split_once('=') {
let action = parse_action(option_value.trim())?;
let option = match option_type.trim().to_ascii_uppercase().as_str() {
"SUCCESS" => Some(WriteCheckpointOption::Success(action)),
"FAILURE" => Some(WriteCheckpointOption::Failure(action)),
"BACKUP" => Some(WriteCheckpointOption::Backup(action)),
other => return Err(Error::Message(format!("unknown WriteCheckpoint option: {other}"))),
};
Ok(Self {
action: WriteCheckpointAction::All,
option,
})
} else {
let action = parse_action(s)?;
Ok(Self {
action,
option: None,
})
}
}
}
fn parse_action(s: &str) -> CResult<WriteCheckpointAction> {
match s.to_ascii_uppercase().as_str() {
"NONE" => Ok(WriteCheckpointAction::None),
"MINIMAL" => Ok(WriteCheckpointAction::Minimal),
"BOTH" => Ok(WriteCheckpointAction::Both),
"ALL" => Ok(WriteCheckpointAction::All),
"FULL" => Ok(WriteCheckpointAction::Full),
other => Err(Error::Message(format!("unknown WriteCheckpointAction: {other}"))),
}
}
impl ToCell for WriteCheckpoint {
fn to_cell(&self) -> Cell<'_> {
let action_str = match self.action {
WriteCheckpointAction::None => "NONE",
WriteCheckpointAction::Minimal => "MINIMAL",
WriteCheckpointAction::Both => "BOTH",
WriteCheckpointAction::All => "ALL",
WriteCheckpointAction::Full => "FULL",
};
if let Some(option) = &self.option {
let (option_prefix, option_action) = match option {
WriteCheckpointOption::Success(a) => ("SUCCESS", a),
WriteCheckpointOption::Failure(a) => ("FAILURE", a),
WriteCheckpointOption::Backup(a) => ("BACKUP", a),
};
let option_action_str = match option_action {
WriteCheckpointAction::None => "NONE",
WriteCheckpointAction::Minimal => "MINIMAL",
WriteCheckpointAction::Both => "BOTH",
WriteCheckpointAction::All => "ALL",
WriteCheckpointAction::Full => "FULL",
};
let full_value = format!("{option_prefix}={option_action_str}");
Cell::KeyValue("WRITE_CHECKPOINT", CellValue::String(full_value))
} else {
Cell::KeyValue(
"WRITE_CHECKPOINT",
CellValue::String(action_str.to_string()),
)
}
}
}
impl ToCellValue for WriteCheckpoint {
fn to_cell_value(&self) -> CellValue<'_> {
let action_str = match self.action {
WriteCheckpointAction::None => "NONE",
WriteCheckpointAction::Minimal => "MINIMAL",
WriteCheckpointAction::Both => "BOTH",
WriteCheckpointAction::All => "ALL",
WriteCheckpointAction::Full => "FULL",
};
if let Some(option) = &self.option {
let (option_prefix, option_action) = match option {
WriteCheckpointOption::Success(a) => ("SUCCESS", a),
WriteCheckpointOption::Failure(a) => ("FAILURE", a),
WriteCheckpointOption::Backup(a) => ("BACKUP", a),
};
let option_action_str = match option_action {
WriteCheckpointAction::None => "NONE",
WriteCheckpointAction::Minimal => "MINIMAL",
WriteCheckpointAction::Both => "BOTH",
WriteCheckpointAction::All => "ALL",
WriteCheckpointAction::Full => "FULL",
};
CellValue::String(format!("{option_prefix}={option_action_str}"))
} else {
CellValue::String(action_str.to_string())
}
}
}