libsignal_rust/
protocol_address.rs

1#[derive(Debug, Clone, PartialEq, Eq)]
2pub struct ProtocolAddress {
3    pub id: String,
4    pub device_id: u32,
5}
6
7impl ProtocolAddress {
8    pub fn from_string(encoded_address: &str) -> Result<Self, Box<dyn std::error::Error>> {
9        Self::from_encoded(encoded_address)
10    }
11
12    pub fn from_encoded(encoded_address: &str) -> Result<Self, Box<dyn std::error::Error>> {
13        if encoded_address.matches('.').count() != 1 {
14            return Err("Invalid address encoding: must contain exactly one '.' character".into());
15        }
16        
17        let parts: Vec<&str> = encoded_address.split('.').collect();
18        if parts.len() != 2 {
19            return Err("Invalid address encoding: must have exactly two parts separated by '.'".into());
20        }
21        
22        if parts[0].is_empty() {
23            return Err("Invalid address encoding: ID part cannot be empty".into());
24        }
25        
26        let device_id = parts[1].parse::<u32>()
27            .map_err(|_| "Invalid device ID: must be a valid 32-bit unsigned integer")?;
28        
29        Self::new(parts[0].to_string(), device_id)
30    }
31
32    pub fn new(id: String, device_id: u32) -> Result<Self, Box<dyn std::error::Error>> {
33        if id.contains('.') {
34            return Err("ProtocolAddress ID cannot contain '.' character - use from_encoded() for encoded addresses".into());
35        }
36        Ok(Self { id, device_id })
37    }
38
39    pub fn to_string(&self) -> String {
40        format!("{}.{}", self.id, self.device_id)
41    }
42
43    pub fn is(&self, other: &Self) -> bool {
44        self.id == other.id && self.device_id == other.device_id
45    }
46}