systemprompt_identifiers/
profile.rs1use crate::error::IdValidationError;
7use crate::{DbValue, ToDbValue};
8use serde::{Deserialize, Serialize};
9use std::fmt;
10
11#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
12#[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
13#[cfg_attr(feature = "sqlx", sqlx(transparent))]
14#[serde(transparent)]
15pub struct ProfileName(String);
16
17impl ProfileName {
18 pub fn try_new(value: impl Into<String>) -> Result<Self, IdValidationError> {
19 let value = value.into();
20 if value.is_empty() {
21 return Err(IdValidationError::empty("ProfileName"));
22 }
23 if value.contains('/') {
24 return Err(IdValidationError::invalid(
25 "ProfileName",
26 "cannot contain path separator '/'",
27 ));
28 }
29 if !value
30 .chars()
31 .all(|c| c.is_alphanumeric() || c == '-' || c == '_')
32 {
33 return Err(IdValidationError::invalid(
34 "ProfileName",
35 "can only contain alphanumeric characters, hyphens, and underscores",
36 ));
37 }
38 Ok(Self(value))
39 }
40
41 #[must_use]
42 pub fn as_str(&self) -> &str {
43 &self.0
44 }
45
46 #[must_use]
47 pub fn default_profile() -> Self {
48 Self("default".to_owned())
49 }
50}
51
52impl fmt::Display for ProfileName {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54 write!(f, "{}", self.0)
55 }
56}
57
58impl TryFrom<String> for ProfileName {
59 type Error = IdValidationError;
60
61 fn try_from(s: String) -> Result<Self, Self::Error> {
62 Self::try_new(s)
63 }
64}
65
66impl TryFrom<&str> for ProfileName {
67 type Error = IdValidationError;
68
69 fn try_from(s: &str) -> Result<Self, Self::Error> {
70 Self::try_new(s)
71 }
72}
73
74impl std::str::FromStr for ProfileName {
75 type Err = IdValidationError;
76
77 fn from_str(s: &str) -> Result<Self, Self::Err> {
78 Self::try_new(s)
79 }
80}
81
82impl AsRef<str> for ProfileName {
83 fn as_ref(&self) -> &str {
84 &self.0
85 }
86}
87
88impl<'de> Deserialize<'de> for ProfileName {
89 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
90 where
91 D: serde::Deserializer<'de>,
92 {
93 let s = String::deserialize(deserializer)?;
94 Self::try_new(s).map_err(serde::de::Error::custom)
95 }
96}
97
98impl ToDbValue for ProfileName {
99 fn to_db_value(&self) -> DbValue {
100 DbValue::String(self.0.clone())
101 }
102}
103
104impl ToDbValue for &ProfileName {
105 fn to_db_value(&self) -> DbValue {
106 DbValue::String(self.0.clone())
107 }
108}