ouch_bindings_python 5.0.1

Python bindings for the OUCH protocol
Documentation
use links_bindings_python::prelude::*;
use links_nonblocking::prelude::*;
use log::info;
use ouch_connect_nonblocking::prelude::*;
use pyo3::{prelude::*, types::PyDict};
use serde::Serialize;
use std::time::Duration;

use crate::{DEFAULT_CONNECT_TIMEOUT, DEFAULT_IO_TIMEOUT, DEFAULT_MAX_HBEAT_INTERVAL, DEFAULT_RETRY_CONNECT_AFTER, DEFAULT_USR_PWD};

create_callback_for_messenger!(CltOuchProtocolManual, CltOuchProtocolManualCallback);
create_clt_sender!(CltManual, CltOuchSender, CltOuchProtocolManual, CltOuchProtocolManualCallback, "ouch_connect");

#[derive(Serialize)]
struct CltManualConfig {
    pub connect_timeout: f64,
    pub retry_connect_after: f64,
    pub io_timeout: f64,
    pub name: String,
}
impl Default for CltManualConfig {
    fn default() -> Self {
        Self {
            connect_timeout: DEFAULT_CONNECT_TIMEOUT,
            retry_connect_after: DEFAULT_RETRY_CONNECT_AFTER,
            io_timeout: DEFAULT_IO_TIMEOUT,
            name: asserted_short_name!("CltManual", CltManual).to_owned(),
        }
    }
}
impl From<&PyDict> for CltManualConfig {
    fn from(py_dict: &PyDict) -> Self {
        let default = Self::default();
        let connect_timeout = py_dict.get_item("connect_timeout").unwrap().map_or(default.connect_timeout, |any| any.extract::<f64>().unwrap());
        let retry_connect_after = py_dict.get_item("retry_connect_after").unwrap().map_or(default.retry_connect_after, |any| any.extract::<f64>().unwrap());
        let io_timeout = py_dict.get_item("io_timeout").unwrap().map_or(default.io_timeout, |any| any.extract::<f64>().unwrap());
        let name = py_dict.get_item("name").unwrap().map_or(default.name, |any| any.extract::<String>().unwrap());
        Self {
            connect_timeout,
            retry_connect_after,
            io_timeout,
            name,
        }
    }
}

#[pymethods]
impl CltManual {
    #[new]
    #[pyo3(signature = (host, callback, **kwargs))]
    fn new(_py: Python<'_>, host: &str, callback: PyObject, kwargs: Option<&PyDict>) -> PyResult<Py<Self>> {
        let config = kwargs.map_or(CltManualConfig::default(), CltManualConfig::from);
        info!("{}: effective config: {} with kwargs: {:?}", asserted_short_name!("CltManual", Self), serde_json::to_string(&config).unwrap(), kwargs);
        let sender = {
            let callback = callback.clone();
            let sender = _py
                .allow_threads(move || {
                    let callback = CltOuchProtocolManualCallback::new_ref(callback);
                    let protocol = CltOuchProtocolManual::default();
                    CltOuch::connect(
                        host,
                        Duration::from_secs_f64(config.connect_timeout),
                        Duration::from_secs_f64(config.retry_connect_after),
                        callback,
                        protocol,
                        Some(config.name.as_str()),
                    )
                })?
                .into_sender_with_spawned_recver();
            let con_id = sender.con_id().clone();
            Py::new(
                _py,
                Self {
                    sender: Some(sender).into(),
                    con_id,
                    io_timeout: Some(config.io_timeout),
                },
            )?
        };
        patch_callback_if_settable_sender!(_py, sender, callback, asserted_short_name!("CltManual", Self));
        Ok(sender)
    }
    #[classattr]
    fn msg_samples() -> Vec<String> {
        ouch_connect_nonblocking::prelude::clt_ouch_default_msgs().iter().map(|m| serde_json::to_string(m).unwrap()).collect::<Vec<_>>()
    }
}

create_callback_for_messenger!(CltOuchProtocolAuto, CltOuchProtocolAutoCallback);
create_clt_sender!(CltAuto, CltOuchSenderRef, CltOuchProtocolAuto, CltOuchProtocolAutoCallback, "ouch_connect");

#[derive(Serialize)]
struct CltAutoConfig {
    pub username: String,
    pub password: String,
    pub session_id: String,
    pub sequence: usize,
    pub clt_max_hbeat_interval: f64,
    pub svc_max_hbeat_interval: f64,
    pub connect_timeout: f64,
    pub retry_connect_after: f64,
    pub io_timeout: f64,
    pub name: String,
}
impl Default for CltAutoConfig {
    fn default() -> Self {
        Self {
            username: DEFAULT_USR_PWD.to_owned(),
            password: DEFAULT_USR_PWD.to_owned(),
            session_id: "".to_owned(),
            sequence: 0,
            clt_max_hbeat_interval: DEFAULT_MAX_HBEAT_INTERVAL,
            svc_max_hbeat_interval: DEFAULT_MAX_HBEAT_INTERVAL,
            connect_timeout: DEFAULT_CONNECT_TIMEOUT,
            retry_connect_after: DEFAULT_RETRY_CONNECT_AFTER,
            io_timeout: DEFAULT_IO_TIMEOUT,
            name: asserted_short_name!("CltAuto", CltAuto).to_owned(),
        }
    }
}
impl From<&PyDict> for CltAutoConfig {
    fn from(value: &PyDict) -> Self {
        let default = Self::default();
        let username = value.get_item("username").unwrap().map_or(default.username, |any| any.extract::<String>().unwrap());
        let password = value.get_item("password").unwrap().map_or(default.password, |any| any.extract::<String>().unwrap());
        let session_id = value.get_item("session_id").unwrap().map_or(default.session_id, |any| any.extract::<String>().unwrap());
        let sequence = value.get_item("sequence").unwrap().map_or(default.sequence, |any| any.extract::<usize>().unwrap());
        let clt_max_hbeat_interval = value.get_item("clt_max_hbeat_interval").unwrap().map_or(default.clt_max_hbeat_interval, |any| any.extract::<f64>().unwrap());
        let svc_max_hbeat_interval = value.get_item("svc_max_hbeat_interval").unwrap().map_or(default.svc_max_hbeat_interval, |any| any.extract::<f64>().unwrap());
        let connect_timeout = value.get_item("connect_timeout").unwrap().map_or(default.connect_timeout, |any| any.extract::<f64>().unwrap());
        let retry_connect_after = value.get_item("retry_connect_after").unwrap().map_or(default.retry_connect_after, |any| any.extract::<f64>().unwrap());
        let io_timeout = value.get_item("io_timeout").unwrap().map_or(default.io_timeout, |any| any.extract::<f64>().unwrap());
        let name = value.get_item("name").unwrap().map_or(default.name, |any| any.extract::<String>().unwrap());
        Self {
            username,
            password,
            session_id,
            sequence,
            clt_max_hbeat_interval,
            svc_max_hbeat_interval,
            connect_timeout,
            retry_connect_after,
            io_timeout,
            name,
        }
    }
}

#[pymethods]
impl CltAuto {
    #[new]
    #[pyo3(signature = (host, callback, **kwargs))]
    fn new(_py: Python<'_>, host: &str, callback: PyObject, kwargs: Option<&PyDict>) -> PyResult<Py<Self>> {
        let config = kwargs.map_or(CltAutoConfig::default(), CltAutoConfig::from);
        info!("{}: effective config: {} with kwargs: {:?}", asserted_short_name!("CltAuto", Self), serde_json::to_string(&config).unwrap(), kwargs);

        let sender = {
            let callback = CltOuchProtocolAutoCallback::new_ref(callback.clone());

            let protocol = CltOuchProtocolAuto::new(
                UserName::from(config.username.as_str()),
                Password::from(config.password.as_str()),
                SessionId::from(config.session_id.as_str()),
                SequenceNumber::from(config.sequence),
                Duration::from_secs_f64(config.io_timeout),
                Duration::from_secs_f64(config.clt_max_hbeat_interval),
                Duration::from_secs_f64(config.svc_max_hbeat_interval),
            );

            let sender = _py
                .allow_threads(move || {
                    CltOuch::connect(
                        host,
                        Duration::from_secs_f64(config.connect_timeout),
                        Duration::from_secs_f64(config.retry_connect_after),
                        callback,
                        protocol,
                        Some(config.name.as_str()),
                    )
                })?
                .into_sender_with_spawned_recver_ref();
            let con_id = sender.con_id().clone();
            Py::new(
                _py,
                Self {
                    sender: Some(sender).into(),
                    con_id,
                    io_timeout: Some(config.io_timeout),
                },
            )?
        };

        patch_callback_if_settable_sender!(_py, sender, callback, asserted_short_name!("CltAuto", Self));
        Ok(sender)
    }
    #[classattr]
    fn msg_samples() -> Vec<String> {
        ouch_connect_nonblocking::prelude::clt_ouch_default_msgs().iter().map(|m| serde_json::to_string(m).unwrap()).collect::<Vec<_>>()
    }
}