pub mod common;
pub mod loopback;
pub mod external;
mod personality;
#[cfg(feature = "sys")]
#[path="sys/mod.rs"]
mod sys_internal;
use crate::wire::Payload;
use crate::layer::{Result, FnHandler};
#[cfg(feature = "std")]
use crate::wire::{ethernet, pretty_print::{Formatter, PrettyPrinter}};
use crate::time::Instant;
pub use self::personality::{
Capabilities,
Personality,
Protocol};
#[cfg(feature = "sys")]
pub use self::sys_internal::exports as sys;
pub use crate::layer::loss::{Lossy, PrngLoss};
pub struct Packet<'a, H, P>
where
H: Handle + ?Sized + 'a,
P: Payload + ?Sized + 'a,
{
pub handle: &'a mut H,
pub payload: &'a mut P,
}
pub trait Handle {
fn queue(&mut self) -> Result<()>;
fn info(&self) -> &dyn Info;
}
pub trait Info {
fn timestamp(&self) -> Instant;
fn capabilities(&self) -> Capabilities;
}
pub trait Device {
type Handle: Handle + ?Sized;
type Payload: Payload + ?Sized;
fn personality(&self) -> Personality;
fn tx(&mut self, max: usize, sender: impl Send<Self::Handle, Self::Payload>)
-> Result<usize>;
fn rx(&mut self, max: usize, receiver: impl Recv<Self::Handle, Self::Payload>)
-> Result<usize>;
}
pub trait Recv<H: Handle + ?Sized, P: Payload + ?Sized> {
fn receive(&mut self, packet: Packet<H, P>);
fn receivev<'a>(&mut self, packets: impl IntoIterator<Item=Packet<'a, H, P>>)
where P: 'a, H: 'a
{
for packet in packets.into_iter() {
self.receive(packet);
}
}
}
pub trait Send<H: Handle + ?Sized, P: Payload + ?Sized> {
fn send(&mut self, packet: Packet<H, P>);
fn sendv<'a>(&mut self, packets: impl IntoIterator<Item=Packet<'a, H, P>>)
where P: 'a, H: 'a
{
for packet in packets.into_iter() {
self.send(packet)
}
}
}
impl<F, H: Handle + ?Sized, P: Payload + ?Sized> Recv<H, P> for FnHandler<F>
where F: FnMut(Packet<H, P>)
{
fn receive(&mut self, packet: Packet<H, P>) {
(self.0)(packet)
}
}
impl<F, H: Handle + ?Sized, P: Payload + ?Sized> Send<H, P> for FnHandler<F>
where F: FnMut(Packet<H, P>)
{
fn send(&mut self, packet: Packet<H, P>) {
(self.0)(packet)
}
}
impl<F, H: Handle + ?Sized, P: Payload + ?Sized> Recv<H, P> for &'_ mut F
where F: Recv<H, P>
{
fn receive(&mut self, packet: Packet<H, P>) {
(**self).receive(packet)
}
fn receivev<'a>(&mut self, packets: impl IntoIterator<Item=Packet<'a, H, P>>)
where P: 'a, H: 'a
{
(**self).receivev(packets)
}
}
impl<F, H: Handle + ?Sized, P: Payload + ?Sized> Send<H, P> for &'_ mut F
where F: Send<H, P>
{
fn send(&mut self, packet: Packet<H, P>) {
(**self).send(packet)
}
fn sendv<'a>(&mut self, packets: impl IntoIterator<Item=Packet<'a, H, P>>)
where P: 'a, H: 'a
{
(**self).sendv(packets)
}
}
#[cfg(feature = "std")]
impl<H: Handle + ?Sized, P: Payload + ?Sized> Recv<H, P> for Formatter<ethernet::frame> {
fn receive(&mut self, frame: Packet<H, P>) {
let printer = PrettyPrinter::<ethernet::frame>
::new("", frame.payload.payload().as_slice());
eprintln!("{}", printer);
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::wire::PayloadMut;
#[derive(Copy, Clone)]
pub(crate) struct LengthIo;
impl LengthIo {
fn signature<P: Payload + ?Sized>(&mut self, payload: &P) -> [u8; 8] {
payload.payload()
.as_slice()
.len()
.to_le_bytes()
}
}
impl<H, P> Recv<H, P> for LengthIo
where H: Handle + ?Sized, P: Payload + ?Sized,
{
fn receive(&mut self, packet: Packet<H, P>) {
let bytes = self.signature(&packet.payload);
for (p, b) in packet.payload.payload().as_slice().iter().zip(bytes.iter().cycle()) {
assert!(p == b)
}
}
}
impl<H, P> Send<H, P> for LengthIo
where H: Handle + ?Sized, P: Payload + PayloadMut + ?Sized,
{
fn send(&mut self, packet: Packet<H, P>) {
let bytes = self.signature(&packet.payload);
for (p, b) in packet.payload.payload_mut().as_mut_slice().iter_mut().zip(bytes.iter().cycle()) {
*p = *b;
}
assert_eq!(packet.handle.queue(), Ok(()));
}
}
}