Skip to main content

systemprompt_models/brain/
status.rs

1//! The lifecycle status of a fact.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use std::fmt;
7use std::str::FromStr;
8
9use schemars::JsonSchema;
10use serde::{Deserialize, Serialize};
11
12/// Where a fact stands: only `Confirmed` facts are recalled; `Stale` ones
13/// only when the profile allows a marked injection.
14#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
15#[serde(rename_all = "snake_case")]
16pub enum FactStatus {
17    Candidate,
18    Proposed,
19    Confirmed,
20    Disputed,
21    Stale,
22    Superseded,
23    Retired,
24}
25
26/// A string that is not a [`FactStatus`].
27#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
28#[error("unknown fact status {0:?}")]
29pub struct UnknownFactStatus(pub String);
30
31impl FactStatus {
32    pub const ALL: [Self; 7] = [
33        Self::Candidate,
34        Self::Proposed,
35        Self::Confirmed,
36        Self::Disputed,
37        Self::Stale,
38        Self::Superseded,
39        Self::Retired,
40    ];
41
42    #[must_use]
43    pub const fn as_str(self) -> &'static str {
44        match self {
45            Self::Candidate => "candidate",
46            Self::Proposed => "proposed",
47            Self::Confirmed => "confirmed",
48            Self::Disputed => "disputed",
49            Self::Stale => "stale",
50            Self::Superseded => "superseded",
51            Self::Retired => "retired",
52        }
53    }
54
55    #[must_use]
56    pub const fn is_recallable(self) -> bool {
57        matches!(self, Self::Confirmed)
58    }
59
60    #[must_use]
61    pub const fn is_terminal(self) -> bool {
62        matches!(self, Self::Superseded | Self::Retired)
63    }
64}
65
66impl fmt::Display for FactStatus {
67    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68        f.write_str(self.as_str())
69    }
70}
71
72impl FromStr for FactStatus {
73    type Err = UnknownFactStatus;
74
75    fn from_str(s: &str) -> Result<Self, Self::Err> {
76        Self::ALL
77            .into_iter()
78            .find(|status| status.as_str() == s)
79            .ok_or_else(|| UnknownFactStatus(s.to_owned()))
80    }
81}