1#[cfg(test)]
2mod tests;
3
4use std::os::fd;
5use std::os::fd::{AsFd, AsRawFd};
6use std::{ffi, ptr};
7
8pub struct Context(ptr::NonNull<libsession_sys::LibsessionContext>);
9
10impl Context {
11 #[must_use]
12 pub fn connect() -> Option<Self> {
13 ptr::NonNull::new(libsession_sys::libsession_new()).map(Self)
14 }
15
16 pub fn get_backend(&self) -> libsession_sys::Result<libsession_sys::LibsessionBackend> {
17 let mut backend = libsession_sys::LibsessionBackend::Sessiond;
18
19 libsession_sys::Result::<()>::from(unsafe {
20 libsession_sys::libsession_get_backend(self.0.as_ptr(), &raw mut backend)
21 })?;
22
23 Ok(backend)
24 }
25
26 pub fn get_session(&self) -> libsession_sys::Result<Session> {
33 let mut id = ptr::null_mut();
34
35 libsession_sys::Result::<()>::from(unsafe {
36 libsession_sys::libsession_get_session(self.0.as_ptr(), &raw mut id)
37 })?;
38
39 let id = ptr::NonNull::new(id).ok_or(libsession_sys::Error::InternalError)?;
40 Ok(Session(id))
41 }
42
43 pub fn get_session_for_pid(&self, pid: i32) -> libsession_sys::Result<Session> {
50 let mut id = ptr::null_mut();
51 libsession_sys::Result::<()>::from(unsafe {
52 libsession_sys::libsession_pid_get_session(self.0.as_ptr(), pid, &raw mut id)
53 })?;
54
55 let id = ptr::NonNull::new(id).ok_or(libsession_sys::Error::InternalError)?;
56 Ok(Session(id))
57 }
58
59 pub fn get_display_for_uid(&self, uid: u32) -> libsession_sys::Result<Session> {
60 let mut id = ptr::null_mut();
61 libsession_sys::Result::<()>::from(unsafe {
62 libsession_sys::libsession_uid_get_display(self.0.as_ptr(), uid, &raw mut id)
63 })?;
64
65 let id = ptr::NonNull::new(id).ok_or(libsession_sys::Error::InternalError)?;
66 Ok(Session(id))
67 }
68
69 pub fn list_sessions(&self) -> libsession_sys::Result<Vec<Session>> {
70 let mut sessions = ptr::null_mut();
71 let mut count = 0usize;
72
73 libsession_sys::Result::<()>::from(unsafe {
74 libsession_sys::libsession_session_list(
75 self.0.as_ptr(),
76 &raw mut sessions,
77 &raw mut count,
78 )
79 })?;
80
81 if count == 0 {
82 return Ok(Vec::new());
83 }
84
85 let sessions = ptr::NonNull::new(sessions).ok_or(libsession_sys::Error::InternalError)?;
86
87 let ids = unsafe { Box::from_raw(ptr::slice_from_raw_parts_mut(sessions.as_ptr(), count)) };
88
89 Ok(ids
90 .iter()
91 .map(|&id| {
92 Session(unsafe { ptr::NonNull::new_unchecked(id) })
94 })
95 .collect())
96 }
97
98 pub fn is_session_local(&self, session: &Session) -> libsession_sys::Result<bool> {
99 let mut is_local = false;
100
101 libsession_sys::Result::<()>::from(unsafe {
102 libsession_sys::libsession_session_is_local(
103 self.0.as_ptr(),
104 session.0.as_ptr(),
105 &raw mut is_local,
106 )
107 })?;
108
109 Ok(is_local)
110 }
111
112 pub fn get_owner_uid_for_pid(&self, pid: i32) -> libsession_sys::Result<u32> {
113 let mut uid = 0u32;
114
115 libsession_sys::Result::<()>::from(unsafe {
116 libsession_sys::libsession_pid_get_owner_uid(self.0.as_ptr(), pid, &raw mut uid)
117 })?;
118
119 Ok(uid)
120 }
121
122 pub fn get_user_state(
123 &self,
124 uid: u32,
125 ) -> libsession_sys::Result<libsession_sys::LibsessionUserState> {
126 let mut state = libsession_sys::LibsessionUserState::Offline;
127
128 libsession_sys::Result::<()>::from(unsafe {
129 libsession_sys::libsession_uid_get_state(self.0.as_ptr(), uid, &raw mut state)
130 })?;
131
132 Ok(state)
133 }
134
135 pub fn get_session_uid(&self, session: &Session) -> libsession_sys::Result<u32> {
136 let mut uid = 0u32;
137
138 libsession_sys::Result::<()>::from(unsafe {
139 libsession_sys::libsession_session_get_uid(
140 self.0.as_ptr(),
141 session.0.as_ptr(),
142 &raw mut uid,
143 )
144 })?;
145
146 Ok(uid)
147 }
148
149 pub fn get_session_state(
150 &self,
151 session: &Session,
152 ) -> libsession_sys::Result<libsession_sys::LibsessionSessionState> {
153 let mut state = libsession_sys::LibsessionSessionState::Unkown;
154
155 libsession_sys::Result::<()>::from(unsafe {
156 libsession_sys::libsession_session_get_state(
157 self.0.as_ptr(),
158 session.0.as_ptr(),
159 &raw mut state,
160 )
161 })?;
162
163 Ok(state)
164 }
165
166 pub fn is_session_active(&self, session: &Session) -> libsession_sys::Result<bool> {
167 let mut is_active = false;
168
169 libsession_sys::Result::<()>::from(unsafe {
170 libsession_sys::libsession_session_is_active(
171 self.0.as_ptr(),
172 session.0.as_ptr(),
173 &raw mut is_active,
174 )
175 })?;
176
177 Ok(is_active)
178 }
179
180 pub unsafe fn set_log_fn(
193 &self,
194 callback: libsession_sys::LibsessionLogFn,
195 ) -> libsession_sys::Result<()> {
196 libsession_sys::Result::<()>::from(unsafe {
197 libsession_sys::libsession_set_log_fn(self.0.as_ptr(), callback)
198 })
199 }
200
201 pub fn set_log_level(
207 &self,
208 level: libsession_sys::LibsessionLogLevel,
209 ) -> libsession_sys::Result<()> {
210 libsession_sys::Result::<()>::from(unsafe {
211 libsession_sys::libsession_set_log_level(self.0.as_ptr(), level)
212 })
213 }
214
215 #[must_use]
217 pub fn get_log_level(&self) -> libsession_sys::LibsessionLogLevel {
218 unsafe { libsession_sys::libsession_get_log_level(self.0.as_ptr()) }
219 }
220
221 pub fn get_monitor(&mut self) -> libsession_sys::Result<Monitor> {
227 ptr::NonNull::new(libsession_sys::libsession_monitor_new(self.0.as_ptr()))
228 .map(Monitor)
229 .ok_or(libsession_sys::Error::Unavailable)
230 }
231}
232
233pub struct Session(ptr::NonNull<libsession_sys::LibsessionSession>);
234
235impl Session {
236 pub fn id(&self) -> libsession_sys::Result<String> {
237 let mut id = ptr::null_mut();
238 unsafe { libsession_sys::libsession_session_get_id(self.0.as_ptr(), &raw mut id) };
239
240 unsafe { ffi::CString::from_raw(id) }
241 .into_string()
242 .map_err(|_| libsession_sys::Error::InvalidData)
243 }
244}
245
246impl Drop for Session {
247 fn drop(&mut self) {
248 unsafe { libsession_sys::libsession_session_free(self.0.as_ptr()) };
249 }
250}
251
252pub struct Monitor(ptr::NonNull<libsession_sys::libsession_monitor>);
253
254impl Monitor {
255 pub fn flush(&mut self) {
256 libsession_sys::libsession_monitor_flush(self.0.as_ptr());
257 }
258}
259
260impl AsRawFd for Monitor {
261 fn as_raw_fd(&self) -> fd::RawFd {
262 libsession_sys::libsession_monitor_fd(self.0.as_ptr())
263 }
264}
265
266impl AsFd for Monitor {
267 fn as_fd(&self) -> fd::BorrowedFd<'_> {
268 unsafe { fd::BorrowedFd::borrow_raw(self.as_raw_fd()) }
269 }
270}
271
272impl Drop for Monitor {
273 fn drop(&mut self) {
274 libsession_sys::libsession_monitor_free(self.0.as_ptr());
275 }
276}
277
278impl Drop for Context {
279 fn drop(&mut self) {
280 libsession_sys::libsession_free(self.0.as_ptr());
281 }
282}