systemprompt_identifiers/
client_session.rs1use crate::error::IdValidationError;
17
18const SESSION_SEGMENT: &str = "_session_";
19
20fn validate(value: &str) -> Result<(), IdValidationError> {
21 let parsed =
22 uuid::Uuid::parse_str(value).map_err(|e| IdValidationError::uuid("ClientSessionId", e))?;
23 if parsed.hyphenated().to_string() != value {
24 return Err(IdValidationError::invalid(
25 "ClientSessionId",
26 "must be a lowercase hyphenated UUID",
27 ));
28 }
29 Ok(())
30}
31
32crate::define_id!(ClientSessionId, validated, schema, validate);
33
34#[derive(serde::Deserialize)]
35struct MetadataUserId {
36 #[serde(rename = "session_id")]
37 raw_session: String,
38}
39
40impl ClientSessionId {
41 pub fn from_metadata_user_id(value: &str) -> Result<Option<Self>, IdValidationError> {
42 let value = value.trim();
43 let session = if value.starts_with('{') {
44 let metadata: MetadataUserId = serde_json::from_str(value)
45 .map_err(|e| IdValidationError::json("ClientSessionId", e))?;
46 Some(metadata.raw_session)
47 } else {
48 value
49 .rsplit_once(SESSION_SEGMENT)
50 .map(|(_, suffix)| suffix.to_owned())
51 };
52 session
53 .map(|value| {
54 let parsed = uuid::Uuid::parse_str(value.trim())
55 .map_err(|e| IdValidationError::uuid("ClientSessionId", e))?;
56 Self::try_new(parsed.hyphenated().to_string())
57 })
58 .transpose()
59 }
60}