Skip to main content

systemprompt_models/modules/
service_category.rs

1//! Service category classification.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use super::api_paths::ApiPaths;
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
10pub enum ServiceCategory {
11    Core,
12    Agent,
13    Mcp,
14    Meta,
15}
16
17impl ServiceCategory {
18    pub const fn base_path(&self) -> &'static str {
19        match self {
20            Self::Core => ApiPaths::CORE_BASE,
21            Self::Agent => ApiPaths::AGENTS_BASE,
22            Self::Mcp => ApiPaths::MCP_BASE,
23            Self::Meta => "/",
24        }
25    }
26
27    pub const fn display_name(&self) -> &'static str {
28        match self {
29            Self::Core => "Core",
30            Self::Agent => "Agent",
31            Self::Mcp => "MCP",
32            Self::Meta => "Meta",
33        }
34    }
35
36    pub fn mount_path(&self, module_name: &str) -> String {
37        if module_name.is_empty() {
38            self.base_path().to_owned()
39        } else {
40            match self {
41                Self::Meta => {
42                    format!("/{module_name}")
43                },
44                Self::Core | Self::Agent | Self::Mcp => {
45                    format!("{}/{}", self.base_path(), module_name)
46                },
47            }
48        }
49    }
50
51    pub fn matches_path(&self, path: &str) -> bool {
52        let base = self.base_path();
53        if base == "/" {
54            path == "/" || path.starts_with("/.well-known") || path.starts_with(ApiPaths::META_BASE)
55        } else {
56            path.starts_with(base)
57        }
58    }
59
60    pub const fn all() -> &'static [Self] {
61        &[Self::Core, Self::Agent, Self::Mcp, Self::Meta]
62    }
63
64    pub fn from_path(path: &str) -> Option<Self> {
65        for category in &[Self::Core, Self::Agent, Self::Mcp] {
66            if category.matches_path(path) {
67                return Some(*category);
68            }
69        }
70        if Self::Meta.matches_path(path) {
71            Some(Self::Meta)
72        } else {
73            None
74        }
75    }
76}