use crate::{addr::Endpoint, auth::*, core::*, error::*, *};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Radio {
inner: Arc<RawSocket>,
}
impl Radio {
pub fn new() -> Result<Self, Error> {
let inner = Arc::new(RawSocket::new(RawSocketType::Radio)?);
Ok(Self { inner })
}
pub fn with_ctx(handle: CtxHandle) -> Result<Self, Error> {
let inner =
Arc::new(RawSocket::with_ctx(RawSocketType::Radio, handle)?);
Ok(Self { inner })
}
pub fn ctx(&self) -> CtxHandle {
self.inner.ctx()
}
pub fn no_drop(&self) -> Result<bool, Error> {
self.inner.no_drop()
}
pub fn set_no_drop(&self, enabled: bool) -> Result<(), Error> {
self.inner.set_no_drop(enabled)
}
pub fn transmit<M, G>(&self, msg: M, group: G) -> Result<(), Error<Msg>>
where
M: Into<Msg>,
G: AsRef<GroupSlice>,
{
let mut msg = msg.into();
msg.set_group(group);
self.send(msg)
}
pub fn try_transmit<M, G>(&self, msg: M, group: G) -> Result<(), Error<Msg>>
where
M: Into<Msg>,
G: AsRef<GroupSlice>,
{
let mut msg = msg.into();
msg.set_group(group);
self.try_send(msg)
}
}
impl GetRawSocket for Radio {
fn raw_socket(&self) -> &RawSocket {
&self.inner
}
}
impl Socket for Radio {}
impl SendMsg for Radio {}
unsafe impl Send for Radio {}
unsafe impl Sync for Radio {}
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(from = "FlatRadioConfig")]
#[serde(into = "FlatRadioConfig")]
pub struct RadioConfig {
socket_config: SocketConfig,
send_config: SendConfig,
no_drop: Option<bool>,
}
impl RadioConfig {
pub fn new() -> Self {
Self::default()
}
pub fn build(&self) -> Result<Radio, Error> {
self.with_ctx(Ctx::global())
}
pub fn with_ctx(&self, handle: CtxHandle) -> Result<Radio, Error> {
let radio = Radio::with_ctx(handle)?;
self.apply(&radio)?;
Ok(radio)
}
pub fn no_drop(&self) -> bool {
self.no_drop.unwrap_or_default()
}
pub fn set_no_drop(&mut self, cond: bool) {
self.no_drop = Some(cond);
}
pub fn apply(&self, radio: &Radio) -> Result<(), Error> {
if let Some(enabled) = self.no_drop {
radio.set_no_drop(enabled)?;
}
self.send_config.apply(radio)?;
self.socket_config.apply(radio)?;
Ok(())
}
}
#[derive(Serialize, Deserialize)]
struct FlatRadioConfig {
connect: Option<Vec<Endpoint>>,
bind: Option<Vec<Endpoint>>,
send_hwm: HighWaterMark,
send_timeout: Period,
no_drop: Option<bool>,
mechanism: Option<Mechanism>,
}
impl From<RadioConfig> for FlatRadioConfig {
fn from(config: RadioConfig) -> Self {
let socket_config = config.socket_config;
let send_config = config.send_config;
Self {
connect: socket_config.connect,
bind: socket_config.bind,
send_hwm: send_config.send_hwm,
send_timeout: send_config.send_timeout,
no_drop: config.no_drop,
mechanism: socket_config.mechanism,
}
}
}
impl From<FlatRadioConfig> for RadioConfig {
fn from(flat: FlatRadioConfig) -> Self {
let socket_config = SocketConfig {
connect: flat.connect,
bind: flat.bind,
mechanism: flat.mechanism,
};
let send_config = SendConfig {
send_hwm: flat.send_hwm,
send_timeout: flat.send_timeout,
};
Self {
socket_config,
send_config,
no_drop: flat.no_drop,
}
}
}
impl GetSocketConfig for RadioConfig {
fn socket_config(&self) -> &SocketConfig {
&self.socket_config
}
fn socket_config_mut(&mut self) -> &mut SocketConfig {
&mut self.socket_config
}
}
impl ConfigureSocket for RadioConfig {}
impl GetSendConfig for RadioConfig {
fn send_config(&self) -> &SendConfig {
&self.send_config
}
fn send_config_mut(&mut self) -> &mut SendConfig {
&mut self.send_config
}
}
impl ConfigureSend for RadioConfig {}
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
pub struct RadioBuilder {
inner: RadioConfig,
}
impl RadioBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn no_drop(&mut self) -> &mut Self {
self.inner.set_no_drop(true);
self
}
pub fn build(&self) -> Result<Radio, Error> {
self.inner.build()
}
pub fn with_ctx(&self, handle: CtxHandle) -> Result<Radio, Error> {
self.inner.with_ctx(handle)
}
}
impl GetSocketConfig for RadioBuilder {
fn socket_config(&self) -> &SocketConfig {
self.inner.socket_config()
}
fn socket_config_mut(&mut self) -> &mut SocketConfig {
self.inner.socket_config_mut()
}
}
impl BuildSocket for RadioBuilder {}
impl GetSendConfig for RadioBuilder {
fn send_config(&self) -> &SendConfig {
self.inner.send_config()
}
fn send_config_mut(&mut self) -> &mut SendConfig {
self.inner.send_config_mut()
}
}
impl BuildSend for RadioBuilder {}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_ser_de() {
let config = RadioConfig::new();
let ron = serde_yaml::to_string(&config).unwrap();
let de: RadioConfig = serde_yaml::from_str(&ron).unwrap();
assert_eq!(config, de);
}
}