use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Default, Deserialize, schemars::JsonSchema, Serialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct State {
#[serde(default)]
pub backend: StateBackendKind,
#[serde(default)]
pub path: Option<String>,
}
#[derive(
Debug, Clone, Copy, Default, Deserialize, schemars::JsonSchema, Serialize, PartialEq, Eq,
)]
#[serde(rename_all = "lowercase")]
pub enum StateBackendKind {
#[default]
Memory,
Redb,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::manifest::Manifest;
#[test]
fn state_defaults_memory_and_parses_redb() {
let bare = Manifest::from_toml("").unwrap();
assert_eq!(bare.state.backend, StateBackendKind::Memory);
assert_eq!(bare.state.path, None);
let m = Manifest::from_toml(
r#"
[state]
backend = "redb"
path = "state/plecto.redb"
"#,
)
.unwrap();
assert_eq!(m.state.backend, StateBackendKind::Redb);
assert_eq!(m.state.path.as_deref(), Some("state/plecto.redb"));
assert!(
Manifest::from_toml("[state]\nbackedn = \"redb\"\n").is_err(),
"a typo inside [state] is rejected"
);
}
#[test]
fn state_rides_the_content_hash_and_the_default_is_canonical() {
let absent = Manifest::from_toml("").unwrap();
let explicit = Manifest::from_toml("[state]\nbackend = \"memory\"\n").unwrap();
assert_eq!(
absent.content_hash().unwrap(),
explicit.content_hash().unwrap(),
"an explicit default [state] must not change the content hash"
);
let redb = Manifest::from_toml("[state]\nbackend = \"redb\"\npath = \"s.redb\"\n").unwrap();
assert_ne!(
absent.content_hash().unwrap(),
redb.content_hash().unwrap(),
"a state-backend change must flip the content hash"
);
}
}