1use std::fmt::Display;
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Default, Serialize, Deserialize)]
6#[serde(rename_all = "kebab-case")]
7pub enum ShareType {
8 #[default]
9 User,
10 Group,
11 Federation,
12}
13
14#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Default, Serialize, Deserialize)]
20#[serde(try_from = "String", into = "String")]
21pub struct OcmAddress {
22 address: String,
23 separator_index: usize
24}
25
26impl OcmAddress {
27 pub fn get_identifier(&self) -> &str {
29 self.address.split_at(self.separator_index).0
30 }
31
32 pub fn get_server_url(&self) -> &str {
35 self.address.split_at(self.separator_index+1).1
36 }
37}
38
39impl TryFrom<&str> for OcmAddress {
40 type Error = &'static str;
41
42 fn try_from(value: &str) -> Result<Self, Self::Error> {
43 value.to_string().try_into()
44 }
45}
46
47impl TryFrom<String> for OcmAddress {
48 type Error = &'static str;
49
50 fn try_from(value: String) -> Result<Self, Self::Error> {
51 let separator_index = value.rfind('@')
52 .ok_or("Missing '@' separator in OCM Address")?;
53 let host = value.split_at(separator_index+1).1;
54
55 if host.contains('/') {
56 Err("OCM Address may not contain a path or scheme")?
57 };
58 Ok(Self {
59 address: value,
60 separator_index
61 })
62 }
63}
64
65impl Display for OcmAddress {
66 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67 f.write_str(&self.address)?;
68 Ok(())
69 }
70}
71
72impl From<OcmAddress> for String {
73 fn from(val: OcmAddress) -> Self {
74 val.address
75 }
76}
77
78#[cfg(test)]
79mod test {
80 use super::OcmAddress;
81
82
83 #[test]
84 fn invalid_ocm_addresses() {
85 OcmAddress::try_from("user@https://example.org").expect_err("Scheme is not allowed in server address part");
86 OcmAddress::try_from("user@example.org/subfolder").expect_err("Scheme is not allowed in server address part");
87 }
88
89 #[test]
90 fn valid_ocm_addresses() {
91 let address = OcmAddress::try_from("asdf@user@example.org").expect("asdf@user@example.org should be accepted");
92 assert_eq!(("asdf@user", "example.org"), (address.get_identifier(), address.get_server_url()));
93
94 let address = OcmAddress::try_from("🤡asdf@user@example.org:8080").expect("🤡asdf@user@example.org:8080 should be accepted");
95 assert_eq!(("🤡asdf@user", "example.org:8080"), (address.get_identifier(), address.get_server_url()));
96
97 let address = OcmAddress::try_from("asdf@user@127.0.0.1").expect("asdf@user@127.0.0.1 should be accepted");
98 assert_eq!(("asdf@user", "127.0.0.1"), (address.get_identifier(), address.get_server_url()));
99
100 let address = OcmAddress::try_from("asdf@user@[fe80::cc7f:2f7d:80f6:3876%en0]").expect("asdf@user@[fe80::cc7f:2f7d:80f6:3876%en0] should be accepted");
101 assert_eq!(("asdf@user", "[fe80::cc7f:2f7d:80f6:3876%en0]"), (address.get_identifier(), address.get_server_url()));
102 }
103}