Skip to main content

systemprompt_models/profile/
runtime.rs

1//! Runtime configuration and enums.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use serde::{Deserialize, Serialize};
7use std::fmt;
8
9#[derive(Debug, Clone, Copy, Serialize, Deserialize, schemars::JsonSchema)]
10#[serde(deny_unknown_fields)]
11pub struct RuntimeConfig {
12    #[serde(default)]
13    pub environment: Environment,
14
15    #[serde(default)]
16    pub log_level: LogLevel,
17
18    #[serde(default)]
19    pub output_format: OutputFormat,
20
21    #[serde(default)]
22    pub no_color: bool,
23
24    #[serde(default)]
25    pub non_interactive: bool,
26}
27
28impl Default for RuntimeConfig {
29    fn default() -> Self {
30        Self {
31            environment: Environment::Development,
32            log_level: LogLevel::Normal,
33            output_format: OutputFormat::Text,
34            no_color: false,
35            non_interactive: false,
36        }
37    }
38}
39
40#[derive(
41    Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default, schemars::JsonSchema,
42)]
43#[serde(rename_all = "lowercase")]
44pub enum Environment {
45    #[default]
46    Development,
47    Test,
48    Staging,
49    Production,
50}
51
52impl Environment {
53    pub const fn is_development(&self) -> bool {
54        matches!(self, Self::Development)
55    }
56
57    pub const fn is_production(&self) -> bool {
58        matches!(self, Self::Production)
59    }
60
61    pub const fn is_test(&self) -> bool {
62        matches!(self, Self::Test)
63    }
64}
65
66impl fmt::Display for Environment {
67    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68        match self {
69            Self::Development => write!(f, "development"),
70            Self::Test => write!(f, "test"),
71            Self::Staging => write!(f, "staging"),
72            Self::Production => write!(f, "production"),
73        }
74    }
75}
76
77impl std::str::FromStr for Environment {
78    type Err = String;
79
80    fn from_str(s: &str) -> Result<Self, Self::Err> {
81        match s.to_lowercase().as_str() {
82            "development" => Ok(Self::Development),
83            "test" => Ok(Self::Test),
84            "staging" => Ok(Self::Staging),
85            "production" => Ok(Self::Production),
86            _ => Err(format!(
87                "Invalid environment '{}'. Must be one of: development, test, staging, production",
88                s
89            )),
90        }
91    }
92}
93
94#[derive(
95    Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default, schemars::JsonSchema,
96)]
97#[serde(rename_all = "lowercase")]
98pub enum LogLevel {
99    Quiet,
100    #[default]
101    Normal,
102    Verbose,
103    Debug,
104}
105
106impl LogLevel {
107    pub const fn as_tracing_filter(&self) -> &'static str {
108        match self {
109            Self::Quiet => "error",
110            Self::Normal => "info",
111            Self::Verbose => "debug",
112            Self::Debug => "trace",
113        }
114    }
115}
116
117impl fmt::Display for LogLevel {
118    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119        match self {
120            Self::Quiet => write!(f, "quiet"),
121            Self::Normal => write!(f, "normal"),
122            Self::Verbose => write!(f, "verbose"),
123            Self::Debug => write!(f, "debug"),
124        }
125    }
126}
127
128impl std::str::FromStr for LogLevel {
129    type Err = String;
130
131    fn from_str(s: &str) -> Result<Self, Self::Err> {
132        match s.to_lowercase().as_str() {
133            "quiet" => Ok(Self::Quiet),
134            "normal" => Ok(Self::Normal),
135            "verbose" => Ok(Self::Verbose),
136            "debug" => Ok(Self::Debug),
137            _ => Err(format!(
138                "Invalid log level '{}'. Must be one of: quiet, normal, verbose, debug",
139                s
140            )),
141        }
142    }
143}
144
145#[derive(
146    Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default, schemars::JsonSchema,
147)]
148#[serde(rename_all = "lowercase")]
149pub enum OutputFormat {
150    #[default]
151    Text,
152    Json,
153    Yaml,
154}
155
156impl fmt::Display for OutputFormat {
157    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158        match self {
159            Self::Text => write!(f, "text"),
160            Self::Json => write!(f, "json"),
161            Self::Yaml => write!(f, "yaml"),
162        }
163    }
164}
165
166impl std::str::FromStr for OutputFormat {
167    type Err = String;
168
169    fn from_str(s: &str) -> Result<Self, Self::Err> {
170        match s.to_lowercase().as_str() {
171            "text" => Ok(Self::Text),
172            "json" => Ok(Self::Json),
173            "yaml" => Ok(Self::Yaml),
174            _ => Err(format!(
175                "Invalid output format '{}'. Must be one of: text, json, yaml",
176                s
177            )),
178        }
179    }
180}