core_crypto/mls/session/
user_id.rs1use super::{Error, Result};
2
3#[derive(Debug, Clone, Copy, Eq, PartialEq, derive_more::Deref)]
11pub struct UserId<'a>(&'a [u8]);
12
13impl UserId<'_> {
14 const USER_ID_DELIMITER: u8 = b':';
15}
16
17impl<'a> TryFrom<&'a str> for UserId<'a> {
18 type Error = Error;
19
20 fn try_from(client_id: &'a str) -> Result<Self> {
21 client_id.as_bytes().try_into()
22 }
23}
24
25impl<'a> TryFrom<&'a [u8]> for UserId<'a> {
26 type Error = Error;
27
28 fn try_from(id: &'a [u8]) -> Result<Self> {
29 let found = id
30 .splitn(2, |&b| b == Self::USER_ID_DELIMITER)
31 .next()
32 .ok_or(Error::InvalidUserId)?;
33 if found.len() == id.len() {
34 return Err(Error::InvalidUserId);
35 }
36 Ok(Self(found))
37 }
38}
39
40impl TryFrom<UserId<'_>> for String {
41 type Error = Error;
42
43 fn try_from(uid: UserId<'_>) -> Result<Self> {
44 Ok(std::str::from_utf8(&uid).map_err(|_| Error::InvalidUserId)?.to_string())
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51 use wasm_bindgen_test::*;
52
53 wasm_bindgen_test_configure!(run_in_browser);
54
55 #[async_std::test]
56 #[wasm_bindgen_test]
57 async fn should_parse_client_id() {
58 let user_id = "LcksJb74Tm6N12cDjFy7lQ:8e6424430d3b28be@world.com";
59 let user_id = UserId::try_from(user_id).unwrap();
60 assert_eq!(user_id, UserId("LcksJb74Tm6N12cDjFy7lQ".as_bytes()));
61 }
62
63 #[async_std::test]
64 #[wasm_bindgen_test]
65 async fn should_fail_when_invalid() {
66 let user_id = "LcksJb74Tm6N12cDjFy7lQ/8e6424430d3b28be@world.com";
67 let user_id = UserId::try_from(user_id);
68 assert!(matches!(user_id.unwrap_err(), Error::InvalidUserId));
69 }
70}