libsignal_protocol/
session_builder.rs

1use crate::{
2    address::Address,
3    context::{Context, ContextInner},
4    errors::{FromInternalErrorCode, InternalError},
5    pre_key_bundle::PreKeyBundle,
6    store_context::{StoreContext, StoreContextInner},
7};
8use std::{
9    fmt::{self, Debug, Formatter},
10    ptr,
11    rc::Rc,
12};
13
14/// Create a new session.
15pub struct SessionBuilder {
16    raw: *mut sys::session_builder,
17    // both these fields must outlive `session_builder`
18    _store_ctx: Rc<StoreContextInner>,
19    _ctx: Rc<ContextInner>,
20    address: Address,
21}
22
23impl SessionBuilder {
24    /// Create a new session builder for communication with the user with the
25    /// specified address.
26    pub fn new(
27        ctx: &Context,
28        store_context: &StoreContext,
29        address: &Address,
30    ) -> SessionBuilder {
31        unsafe {
32            let mut raw = ptr::null_mut();
33            sys::session_builder_create(
34                &mut raw,
35                store_context.raw(),
36                address.raw(),
37                ctx.raw(),
38            );
39
40            SessionBuilder {
41                raw,
42                _store_ctx: Rc::clone(&store_context.0),
43                _ctx: Rc::clone(&ctx.0),
44                address: address.clone(),
45            }
46        }
47    }
48
49    /// Build a session using a pre-key retrieved from the server.
50    pub fn process_pre_key_bundle(
51        &self,
52        pre_key_bundle: &PreKeyBundle,
53    ) -> Result<(), InternalError> {
54        unsafe {
55            sys::session_builder_process_pre_key_bundle(
56                self.raw,
57                pre_key_bundle.raw.as_ptr(),
58            )
59            .into_result()
60        }
61    }
62}
63
64impl Drop for SessionBuilder {
65    fn drop(&mut self) {
66        unsafe {
67            sys::session_builder_free(self.raw);
68        }
69    }
70}
71
72impl Debug for SessionBuilder {
73    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
74        f.debug_struct("SessionBuilder")
75            .field("address", &self.address)
76            .finish()
77    }
78}