libsignal_rust/
protocol_address.rs1#[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}