1pub use converge_pack::Suggestor;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
17pub struct SuggestorId(pub(crate) u32);
18
19impl SuggestorId {
20 #[must_use]
22 pub fn as_u32(self) -> u32 {
23 self.0
24 }
25}
26
27impl std::fmt::Display for SuggestorId {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 write!(f, "Suggestor({})", self.0)
30 }
31}
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36 use crate::context::ContextKey;
37 use crate::effect::AgentEffect;
38
39 struct TestSuggestor {
41 fact_id: String,
42 }
43
44 #[async_trait::async_trait]
45 impl Suggestor for TestSuggestor {
46 fn name(&self) -> &str {
47 "TestSuggestor"
48 }
49
50 fn dependencies(&self) -> &[ContextKey] {
51 &[ContextKey::Seeds]
52 }
53
54 fn accepts(&self, ctx: &dyn crate::ContextView) -> bool {
55 !ctx.get(ContextKey::Seeds)
56 .iter()
57 .any(|f| f.id == self.fact_id)
58 }
59
60 async fn execute(&self, _ctx: &dyn crate::ContextView) -> AgentEffect {
61 AgentEffect::with_proposal(crate::ProposedFact::new(
62 ContextKey::Seeds,
63 self.fact_id.clone(),
64 "test content",
65 self.name(),
66 ))
67 }
68 }
69
70 #[test]
71 fn suggestor_accepts_when_fact_missing() {
72 let suggestor = TestSuggestor {
73 fact_id: "test-1".into(),
74 };
75 let ctx = crate::context::Context::new();
76 assert!(suggestor.accepts(&ctx));
77 }
78
79 #[test]
80 fn suggestor_rejects_when_fact_present() {
81 let suggestor = TestSuggestor {
82 fact_id: "test-1".into(),
83 };
84 let mut ctx = crate::context::Context::new();
85 let fact = converge_pack::fact::kernel_authority::new_fact(
86 ContextKey::Seeds,
87 "test-1",
88 "already here",
89 );
90 let _ = ctx.add_fact(fact);
91 assert!(!suggestor.accepts(&ctx));
92 }
93
94 #[tokio::test]
95 async fn suggestor_produces_effect() {
96 let suggestor = TestSuggestor {
97 fact_id: "test-1".into(),
98 };
99 let ctx = crate::context::Context::new();
100 let effect = suggestor.execute(&ctx).await;
101 assert_eq!(effect.proposals.len(), 1);
102 assert_eq!(effect.proposals[0].id, "test-1");
103 }
104
105 #[test]
106 fn suggestor_id_ordering() {
107 let a = SuggestorId(1);
108 let b = SuggestorId(2);
109 let c = SuggestorId(1);
110 assert!(a < b);
111 assert_eq!(a, c);
112 }
113}