libsignal_service/
proto.rs

1#![allow(clippy::all)]
2
3use libsignal_core::{Aci, ServiceId};
4use rand::{CryptoRng, Rng};
5use reqwest::StatusCode;
6include!(concat!(env!("OUT_DIR"), "/signalservice.rs"));
7include!(concat!(env!("OUT_DIR"), "/signal.rs"));
8
9impl WebSocketRequestMessage {
10    /// Equivalent of
11    /// `SignalServiceMessagePipe::isSignalServiceEnvelope(WebSocketMessage)`.
12    pub fn is_signal_service_envelope(&self) -> bool {
13        self.verb.as_deref() == Some("PUT")
14            && self.path.as_deref() == Some("/api/v1/message")
15    }
16
17    pub fn is_queue_empty(&self) -> bool {
18        self.verb.as_deref() == Some("PUT")
19            && self.path.as_deref() == Some("/api/v1/queue/empty")
20    }
21}
22
23impl WebSocketResponseMessage {
24    /// Equivalent of
25    /// `SignalServiceMessagePipe::isSignalServiceEnvelope(WebSocketMessage)`.
26    pub fn from_request(msg: &WebSocketRequestMessage) -> Self {
27        if msg.is_signal_service_envelope() || msg.is_queue_empty() {
28            WebSocketResponseMessage {
29                id: msg.id,
30                status: Some(200),
31                message: Some("OK".to_string()),
32                ..Default::default()
33            }
34        } else {
35            WebSocketResponseMessage {
36                id: msg.id,
37                status: Some(400),
38                message: Some("Unknown".to_string()),
39                ..Default::default()
40            }
41        }
42    }
43
44    pub fn status_code(&self) -> Option<reqwest::StatusCode> {
45        StatusCode::from_u16(self.status().try_into().ok()?).ok()
46    }
47}
48
49impl SyncMessage {
50    pub fn with_padding<R: Rng + CryptoRng>(csprng: &mut R) -> Self {
51        let random_size = csprng.random_range(1..=512);
52        let mut padding: Vec<u8> = vec![0; random_size];
53        csprng.fill_bytes(&mut padding);
54
55        Self {
56            padding: Some(padding),
57            ..Default::default()
58        }
59    }
60}
61
62impl sync_message::Sent {
63    pub fn parse_destination_service_id(&self) -> Option<ServiceId> {
64        crate::utils::parse_service_id_with_fallback(
65            self.destination_service_id_binary.as_deref(),
66            self.destination_service_id.as_deref(),
67        )
68    }
69}
70
71impl data_message::Reaction {
72    pub fn parse_target_author_aci(&self) -> Option<Aci> {
73        crate::utils::parse_aci_with_fallback(
74            self.target_author_aci_binary.as_deref(),
75            self.target_author_aci.as_deref(),
76        )
77    }
78}
79
80impl data_message::Quote {
81    pub fn parse_author_aci(&self) -> Option<Aci> {
82        crate::utils::parse_aci_with_fallback(
83            self.author_aci_binary.as_deref(),
84            self.author_aci.as_deref(),
85        )
86    }
87}
88
89impl data_message::StoryContext {
90    pub fn parse_author_aci(&self) -> Option<Aci> {
91        crate::utils::parse_aci_with_fallback(
92            self.author_aci_binary.as_deref(),
93            self.author_aci.as_deref(),
94        )
95    }
96}
97
98impl data_message::PollVote {
99    pub fn parse_target_author_aci(&self) -> Option<Aci> {
100        crate::utils::parse_aci_with_fallback(
101            self.target_author_aci_binary.as_deref(),
102            None,
103        )
104    }
105}
106
107impl data_message::PinMessage {
108    pub fn parse_target_author_aci(&self) -> Option<Aci> {
109        crate::utils::parse_aci_with_fallback(
110            self.target_author_aci_binary.as_deref(),
111            None,
112        )
113    }
114}
115
116impl data_message::UnpinMessage {
117    pub fn parse_target_author_aci(&self) -> Option<Aci> {
118        crate::utils::parse_aci_with_fallback(
119            self.target_author_aci_binary.as_deref(),
120            None,
121        )
122    }
123}
124
125impl Verified {
126    pub fn parse_destination_aci(&self) -> Option<Aci> {
127        crate::utils::parse_aci_with_fallback(
128            self.destination_aci_binary.as_deref(),
129            self.destination_aci.as_deref(),
130        )
131    }
132}
133
134impl sync_message::sent::UnidentifiedDeliveryStatus {
135    pub fn parse_destination_service_id(&self) -> Option<ServiceId> {
136        crate::utils::parse_service_id_with_fallback(
137            self.destination_service_id_binary.as_deref(),
138            self.destination_service_id.as_deref(),
139        )
140    }
141}
142
143impl sync_message::sent::StoryMessageRecipient {
144    pub fn parse_destination_service_id(&self) -> Option<ServiceId> {
145        crate::utils::parse_service_id_with_fallback(
146            self.destination_service_id_binary.as_deref(),
147            self.destination_service_id.as_deref(),
148        )
149    }
150}
151
152impl sync_message::Read {
153    pub fn parse_sender_aci(&self) -> Option<Aci> {
154        crate::utils::parse_aci_with_fallback(
155            self.sender_aci_binary.as_deref(),
156            self.sender_aci.as_deref(),
157        )
158    }
159}
160
161impl sync_message::Viewed {
162    pub fn parse_sender_aci(&self) -> Option<Aci> {
163        crate::utils::parse_aci_with_fallback(
164            self.sender_aci_binary.as_deref(),
165            self.sender_aci.as_deref(),
166        )
167    }
168}
169
170impl sync_message::ViewOnceOpen {
171    pub fn parse_sender_aci(&self) -> Option<Aci> {
172        crate::utils::parse_aci_with_fallback(
173            self.sender_aci_binary.as_deref(),
174            self.sender_aci.as_deref(),
175        )
176    }
177}
178
179impl sync_message::MessageRequestResponse {
180    pub fn parse_thread_aci(&self) -> Option<Aci> {
181        crate::utils::parse_aci_with_fallback(
182            self.thread_aci_binary.as_deref(),
183            self.thread_aci.as_deref(),
184        )
185    }
186}
187
188impl ContactDetails {
189    pub fn parse_aci(&self) -> Option<Aci> {
190        crate::utils::parse_aci_with_fallback(
191            self.aci_binary.as_deref(),
192            self.aci.as_deref(),
193        )
194    }
195}