plecto_control/manifest/
state.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Default, Deserialize, schemars::JsonSchema, Serialize, PartialEq, Eq)]
12#[serde(deny_unknown_fields)]
13pub struct State {
14 #[serde(default)]
15 pub backend: StateBackendKind,
16 #[serde(default)]
19 pub path: Option<String>,
20}
21
22#[derive(
24 Debug, Clone, Copy, Default, Deserialize, schemars::JsonSchema, Serialize, PartialEq, Eq,
25)]
26#[serde(rename_all = "lowercase")]
27pub enum StateBackendKind {
28 #[default]
29 Memory,
30 Redb,
31}
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36 use crate::manifest::Manifest;
37
38 #[test]
41 fn state_defaults_memory_and_parses_redb() {
42 let bare = Manifest::from_toml("").unwrap();
44 assert_eq!(bare.state.backend, StateBackendKind::Memory);
45 assert_eq!(bare.state.path, None);
46
47 let m = Manifest::from_toml(
49 r#"
50[state]
51backend = "redb"
52path = "state/plecto.redb"
53"#,
54 )
55 .unwrap();
56 assert_eq!(m.state.backend, StateBackendKind::Redb);
57 assert_eq!(m.state.path.as_deref(), Some("state/plecto.redb"));
58
59 assert!(
61 Manifest::from_toml("[state]\nbackedn = \"redb\"\n").is_err(),
62 "a typo inside [state] is rejected"
63 );
64 }
65
66 #[test]
67 fn state_rides_the_content_hash_and_the_default_is_canonical() {
68 let absent = Manifest::from_toml("").unwrap();
71 let explicit = Manifest::from_toml("[state]\nbackend = \"memory\"\n").unwrap();
72 assert_eq!(
73 absent.content_hash().unwrap(),
74 explicit.content_hash().unwrap(),
75 "an explicit default [state] must not change the content hash"
76 );
77
78 let redb = Manifest::from_toml("[state]\nbackend = \"redb\"\npath = \"s.redb\"\n").unwrap();
81 assert_ne!(
82 absent.content_hash().unwrap(),
83 redb.content_hash().unwrap(),
84 "a state-backend change must flip the content hash"
85 );
86 }
87}