systemprompt_models/brain/
scope.rs1use std::fmt;
8use std::str::FromStr;
9
10use schemars::JsonSchema;
11use serde::{Deserialize, Serialize};
12use systemprompt_identifiers::UserId;
13
14#[derive(
16 Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, JsonSchema,
17)]
18#[serde(rename_all = "snake_case")]
19pub enum ScopeLevel {
20 User,
21 Project,
22 Group,
23 Org,
24}
25
26#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
28#[error("unknown fact scope {0:?}")]
29pub struct UnknownScopeLevel(pub String);
30
31impl ScopeLevel {
32 pub const ALL: [Self; 4] = [Self::User, Self::Project, Self::Group, Self::Org];
33
34 #[must_use]
35 pub const fn as_str(self) -> &'static str {
36 match self {
37 Self::User => "user",
38 Self::Project => "project",
39 Self::Group => "group",
40 Self::Org => "org",
41 }
42 }
43}
44
45impl fmt::Display for ScopeLevel {
46 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47 f.write_str(self.as_str())
48 }
49}
50
51impl FromStr for ScopeLevel {
52 type Err = UnknownScopeLevel;
53
54 fn from_str(s: &str) -> Result<Self, Self::Err> {
55 Self::ALL
56 .into_iter()
57 .find(|level| level.as_str() == s)
58 .ok_or_else(|| UnknownScopeLevel(s.to_owned()))
59 }
60}
61
62#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
64#[serde(tag = "level", content = "key", rename_all = "snake_case")]
65pub enum FactScope {
66 User(UserId),
67 Project(String),
68 Group(String),
69 Org,
70}
71
72impl FactScope {
73 #[must_use]
74 pub const fn level(&self) -> ScopeLevel {
75 match self {
76 Self::User(_) => ScopeLevel::User,
77 Self::Project(_) => ScopeLevel::Project,
78 Self::Group(_) => ScopeLevel::Group,
79 Self::Org => ScopeLevel::Org,
80 }
81 }
82
83 #[must_use]
84 pub fn key(&self) -> Option<&str> {
85 match self {
86 Self::User(user) => Some(user.as_str()),
87 Self::Project(key) | Self::Group(key) => Some(key),
88 Self::Org => None,
89 }
90 }
91}