use crate::error::McrxError;
use crate::platform::{
RawReceiveSocket, join_raw_multicast_group, leave_raw_multicast_group, recv_raw_packet,
};
use crate::raw::{RawPacket, RawSubscriptionConfig};
use crate::subscription::{SubscriptionId, SubscriptionState};
#[derive(Debug)]
pub struct RawSubscription {
id: SubscriptionId,
config: RawSubscriptionConfig,
socket: RawReceiveSocket,
state: SubscriptionState,
}
impl RawSubscription {
pub(crate) fn new(
id: SubscriptionId,
config: RawSubscriptionConfig,
socket: RawReceiveSocket,
) -> Self {
Self {
id,
config,
socket,
state: SubscriptionState::Bound,
}
}
pub fn id(&self) -> SubscriptionId {
self.id
}
pub fn config(&self) -> &RawSubscriptionConfig {
&self.config
}
pub fn socket(&self) -> &socket2::Socket {
self.socket.socket()
}
pub fn state(&self) -> SubscriptionState {
self.state
}
pub fn is_joined(&self) -> bool {
matches!(self.state, SubscriptionState::Joined)
}
pub fn try_recv(&self) -> Result<Option<RawPacket>, McrxError> {
if !self.is_joined() {
return Err(McrxError::SubscriptionNotJoined);
}
recv_raw_packet(&self.socket, self.id, &self.config)
}
pub fn join(&mut self) -> Result<(), McrxError> {
if self.is_joined() {
return Err(McrxError::SubscriptionAlreadyJoined);
}
join_raw_multicast_group(&self.socket, &self.config)?;
self.state = SubscriptionState::Joined;
Ok(())
}
pub fn leave(&mut self) -> Result<(), McrxError> {
if !self.is_joined() {
return Err(McrxError::SubscriptionNotJoined);
}
leave_raw_multicast_group(&self.socket, &self.config)?;
self.state = SubscriptionState::Bound;
Ok(())
}
#[cfg(unix)]
pub fn as_raw_fd(&self) -> std::os::fd::RawFd {
use std::os::fd::AsRawFd;
self.socket().as_raw_fd()
}
#[cfg(windows)]
pub fn as_raw_socket(&self) -> std::os::windows::io::RawSocket {
use std::os::windows::io::AsRawSocket;
self.socket().as_raw_socket()
}
}