mlua_swarm/enhance/
setting.rs1use crate::application::VersionSelector;
16use crate::blueprint::store::BlueprintId;
17use crate::blueprint::Blueprint;
18use serde::{Deserialize, Serialize};
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct EnhanceSetting {
24 pub id: String,
26 pub blueprint_id: BlueprintId,
28 pub ttl_secs: u64,
30 #[serde(default)]
33 pub version: VersionSelector,
34 #[serde(default = "default_verifier_axes")]
40 pub verifier_axes: Vec<String>,
41 #[serde(default)]
43 pub meta: EnhanceSettingMeta,
44}
45
46fn default_verifier_axes() -> Vec<String> {
47 vec![
48 "des".to_string(),
49 "canonical".to_string(),
50 "noop".to_string(),
51 "agent-ref".to_string(),
52 ]
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
59pub struct EnhanceSettingInput {
60 pub id: String,
62 pub blueprint: Blueprint,
65 pub ttl_secs: u64,
67 #[serde(default)]
69 pub version: VersionSelector,
70 #[serde(default = "default_verifier_axes")]
73 pub verifier_axes: Vec<String>,
74 #[serde(default)]
76 pub meta: EnhanceSettingMeta,
77}
78
79impl EnhanceSettingInput {
80 pub fn into_ref(self) -> (Blueprint, EnhanceSetting) {
84 let blueprint_id = BlueprintId::new(self.blueprint.id.clone());
85 (
86 self.blueprint,
87 EnhanceSetting {
88 id: self.id,
89 blueprint_id,
90 ttl_secs: self.ttl_secs,
91 version: self.version,
92 verifier_axes: self.verifier_axes,
93 meta: self.meta,
94 },
95 )
96 }
97}
98
99#[derive(Debug, Clone, Default, Serialize, Deserialize)]
102pub struct EnhanceSettingMeta {}
103
104#[cfg(test)]
105mod tests {
106 use super::*;
107 use crate::enhance::blueprint::default_blueprint;
108
109 #[test]
110 fn default_verifier_axes_has_4_canonical_axes() {
111 let axes = default_verifier_axes();
112 assert_eq!(axes, vec!["des", "canonical", "noop", "agent-ref"]);
113 }
114
115 #[test]
116 fn input_into_ref_splits_blueprint_and_setting() {
117 let bp = default_blueprint();
118 let bp_id = bp.id.clone();
119 let input = EnhanceSettingInput {
120 id: "s1".into(),
121 blueprint: bp,
122 ttl_secs: 60,
123 version: VersionSelector::default(),
124 verifier_axes: default_verifier_axes(),
125 meta: EnhanceSettingMeta::default(),
126 };
127 let (split_bp, setting) = input.into_ref();
128 assert_eq!(setting.id, "s1");
129 assert_eq!(setting.blueprint_id.as_str(), bp_id);
130 assert_eq!(setting.ttl_secs, 60);
131 assert_eq!(setting.verifier_axes.len(), 4);
132 assert_eq!(split_bp.id, bp_id);
133 }
134
135 #[test]
136 fn setting_serde_roundtrip_preserves_verifier_axes() {
137 let bp_id = BlueprintId::new("bp-xyz".to_string());
138 let s = EnhanceSetting {
139 id: "s2".into(),
140 blueprint_id: bp_id,
141 ttl_secs: 30,
142 version: VersionSelector::default(),
143 verifier_axes: vec!["des".into(), "noop".into()],
144 meta: EnhanceSettingMeta::default(),
145 };
146 let j = serde_json::to_value(&s).unwrap();
147 let s2: EnhanceSetting = serde_json::from_value(j).unwrap();
148 assert_eq!(s2.verifier_axes, vec!["des", "noop"]);
149 assert_eq!(s2.ttl_secs, 30);
150 }
151
152 #[test]
153 fn setting_deserialize_applies_default_verifier_axes_when_omitted() {
154 let json = serde_json::json!({
155 "id": "s3",
156 "blueprint_id": "bp-1",
157 "ttl_secs": 10,
158 });
159 let s: EnhanceSetting = serde_json::from_value(json).unwrap();
160 assert_eq!(s.verifier_axes, default_verifier_axes());
161 }
162}