tdlib_json_sys/
lib.rs

1//! Bindings to the TDLib (Telegram Database library) JSON API.
2
3use std::{
4    ffi::{CStr, CString},
5    os::raw::{c_char, c_double, c_int},
6};
7
8#[link(name = "tdjson")]
9extern "C" {
10    fn td_create_client_id() -> c_int;
11    fn td_send(client_id: c_int, request: *const c_char);
12    fn td_receive(timeout: c_double) -> *const c_char;
13    fn td_execute(request: *const c_char) -> *const c_char;
14}
15
16#[derive(Debug, Clone)]
17pub struct TDLib {
18    client_id: i32,
19}
20
21impl TDLib {
22    /// Creates a new instance of TDLib.
23    pub fn new() -> Self {
24        Self {
25            client_id: unsafe { td_create_client_id() },
26        }
27    }
28
29    /// Sends request to the TDLib client.
30    ///
31    /// May be called from any thread.
32    pub fn send(&self, request: &str) {
33        let cstring = CString::new(request).unwrap();
34        unsafe { td_send(self.client_id, cstring.as_ptr()) }
35    }
36
37    /// Synchronously executes TDLib request.
38    ///
39    /// May be called from any thread. Only a few requests can be executed synchronously.
40    pub fn execute(request: &str) -> Option<String> {
41        let cstring = CString::new(request).unwrap();
42        unsafe {
43            td_execute(cstring.as_ptr())
44                .as_ref()
45                .map(|response| CStr::from_ptr(response).to_string_lossy().into_owned())
46        }
47    }
48
49    /// Receives incoming updates and request responses from the TDLib client.
50    ///
51    /// May be called from any thread, but shouldn't be called simultaneously
52    /// from two different threads.
53    pub fn receive(timeout: f64) -> Option<String> {
54        unsafe {
55            td_receive(timeout)
56                .as_ref()
57                .map(|response| CStr::from_ptr(response).to_string_lossy().into_owned())
58        }
59    }
60}
61
62impl Default for TDLib {
63    fn default() -> Self {
64        Self::new()
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::TDLib;
71
72    #[test]
73    fn test_execute() {
74        //let client = TdClient::new();
75
76        let result = TDLib::execute(
77            r#"{"@type":"setLogVerbosityLevel","new_verbosity_level":1,"@extra":1.01234}"#,
78        )
79        .unwrap();
80
81        assert_eq!(result, r#"{"@type":"ok","@extra":1.01234}"#);
82    }
83}