Skip to main content

webex_message_handler/
id_utils.rs

1//! Convert between Mercury activity UUIDs and Webex REST API IDs.
2
3use base64::{Engine as _, engine::general_purpose::STANDARD};
4
5/// Convert a Mercury activity UUID to a Webex REST API ID.
6///
7/// Mercury uses raw UUIDs; the REST API uses base64-encoded
8/// `ciscospark://us/{type}/{uuid}` URIs.
9///
10/// `resource_type` should be `"MESSAGE"`, `"PEOPLE"`, or `"ROOM"`.
11pub fn to_rest_id(uuid: &str, resource_type: &str) -> String {
12    let uri = format!("ciscospark://us/{}/{}", resource_type, uuid);
13    STANDARD.encode(uri.as_bytes())
14}
15
16/// Convert a Webex REST API ID back to a raw UUID.
17pub fn from_rest_id(rest_id: &str) -> Result<String, String> {
18    let decoded = STANDARD
19        .decode(rest_id)
20        .map_err(|e| format!("invalid base64 in REST ID: {e}"))?;
21    let s = String::from_utf8(decoded)
22        .map_err(|e| format!("invalid UTF-8 in REST ID: {e}"))?;
23    let last_slash = s.rfind('/').ok_or_else(|| format!("invalid REST ID format: {rest_id}"))?;
24    Ok(s[last_slash + 1..].to_string())
25}
26
27#[cfg(test)]
28mod tests {
29    use super::*;
30
31    #[test]
32    fn test_roundtrip() {
33        let uuid = "abc-123-def";
34        let rest = to_rest_id(uuid, "MESSAGE");
35        let back = from_rest_id(&rest).unwrap();
36        assert_eq!(back, uuid);
37    }
38
39    #[test]
40    fn test_invalid_base64() {
41        assert!(from_rest_id("!!!invalid!!!").is_err());
42    }
43}