diff options
Diffstat (limited to 'src/raw_ptr.rs')
-rw-r--r-- | src/raw_ptr.rs | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/src/raw_ptr.rs b/src/raw_ptr.rs new file mode 100644 index 0000000..5e2bdde --- /dev/null +++ b/src/raw_ptr.rs @@ -0,0 +1,150 @@ +use crate::error::TdlibSysError; +use libc::c_char; +use std::ffi::CStr; +use std::ffi::CString; + +#[derive(Debug)] +pub struct TdPtr(*mut tdlib_sys::TdLibRawPtr); + +// Send + Sync is guaranteed by TDLib +unsafe impl Send for TdPtr {} +unsafe impl Sync for TdPtr {} + +/// TDLib uses 6 fixed logging levels +/// +/// You can also set even more logging through `More` variant, +/// providing desired logging level +#[derive(Debug, PartialEq, Eq)] +pub enum LogLevel { + Fatal, + Error, + Warn, + Info, + Debug, + Verbose, + /// This sets more verbose logging. + /// + /// Must be between 6 and 1024 inclusively + More(u16), +} + +impl std::default::Default for LogLevel { + fn default() -> Self { + Self::Verbose // 5 is default value from tdlib's docs + } +} + +impl TdPtr { + /// Sets the verbosity level of the internal logging of TDLib. + /// By default the TDLib uses a log verbosity level of 5 (meaning [`LogLevel::Verbose`]). + pub fn set_log_verbosity_level(level: LogLevel) -> Result<(), TdlibSysError> { + let numeric_level: i32 = match level { + LogLevel::Fatal => 0, + LogLevel::Error => 1, + LogLevel::Warn => 2, + LogLevel::Info => 3, + LogLevel::Debug => 4, + LogLevel::Verbose => 5, + LogLevel::More(n) => { + if n > 1024 { + return Err(TdlibSysError::LogLevelOutOfBounds(n)); + } else { + n as i32 + } + } + }; + unsafe { tdlib_sys::td_set_log_verbosity_level(numeric_level) }; + Ok(()) + } + + /// Sets the maximum size of the file to where the internal TDLib log is written + /// before the file will be auto-rotated. + /// + /// Unused if log is not written to a file. Defaults to 10 MB. + pub fn set_log_max_file_size(size: i64) { + unsafe { tdlib_sys::td_set_log_max_file_size(size) }; + } + + /// Sets the path to the file where the internal TDLib log will be written. + /// + /// By default TDLib writes logs to stderr or an OS specific log. + /// + /// Use this method to write the log to a file instead. + pub fn set_log_file_path<S: AsRef<str>>(path: S) -> Result<(), TdlibSysError> { + let cpath = CString::new(path.as_ref())?; + if unsafe { tdlib_sys::td_set_log_file_path(cpath.as_ptr()) } == 0 { + Err(TdlibSysError::CannotSetLogFile) + } else { + Ok(()) + } + } + + /// Resets log file. + /// + /// This function reverts writing to a log file and restores + /// default behaviour for logging. At the time of writing, this means + /// logging to stderr + pub fn reset_log_file_path() -> Result<(), TdlibSysError> { + if unsafe { tdlib_sys::td_set_log_file_path(std::ptr::null()) } == 0 { + Err(TdlibSysError::CannotSetLogFile) + } else { + Ok(()) + } + } + + /// Creates a new instance of TDLib. + pub fn new() -> Self { + Self(unsafe { tdlib_sys::td_json_client_create() }) + } + + /// Sends request to the TDLib client. + /// + /// May be called from any thread. + pub fn send(&self, request: &str) -> Result<(), TdlibSysError> { + let cstring = CString::new(request)?; + unsafe { tdlib_sys::td_json_client_send(self.0, cstring.as_ptr()) }; + Ok(()) + } + + /// Receives incoming updates and request responses from the TDLib client. + /// + /// May be called from any thread, but must not be called simultaneously + /// from two different threads. + pub fn execute(&self, request: &str) -> Result<Option<String>, TdlibSysError> { + let repr_c = CString::new(request)?.as_ptr(); + Ok(Self::string_from_mut_char(unsafe { + tdlib_sys::td_json_client_execute(self.0, repr_c) + })) + } + + /// Receives incoming updates and request responses from the TDLib client. + /// + /// May be called from any thread, but shouldn't be called simultaneously + /// from two different threads. + pub fn receive(&self, timeout: f64) -> Option<String> { + Self::string_from_mut_char(unsafe { tdlib_sys::td_json_client_receive(self.0, timeout) }) + } + + /// Convert `*mut c_char` into String. + /// + /// Returns None if `ptr` is null + fn string_from_mut_char(ptr: *mut c_char) -> Option<String> { + let cstr = unsafe { CStr::from_ptr(ptr.as_ref()?) }; + Some(cstr.to_string_lossy().into_owned()) + } +} + +impl Drop for TdPtr { + fn drop(&mut self) { + unsafe { + tdlib_sys::td_json_client_destroy(self.0); + } + } +} + +mod tests { + #[test] + fn test_create() { + let _td = super::TdPtr::new(); + } +} |