blob: 1c5caa2fd1104b5e9ce45b4307ec3b9741bfa8e3 [file] [log] [blame]
use crate::{Ethernet2Header, LinuxSllHeader};
/// The possible headers on the link layer
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum LinkHeader {
LinuxSll(LinuxSllHeader),
Ethernet2(Ethernet2Header),
}
impl LinkHeader {
/// Returns `Option::Some` containing the `Ethernet2Header` if self has the
/// value Ethernet2. Otherwise `Option::None` is returned.
pub fn ethernet2(self) -> Option<Ethernet2Header> {
use crate::LinkHeader::*;
if let Ethernet2(value) = self {
Some(value)
} else {
None
}
}
/// Returns `Option::Some` containing the `Ethernet2Header` if self has the
/// value Ethernet2. Otherwise `Option::None` is returned.
pub fn mut_ethernet2(&mut self) -> Option<&mut Ethernet2Header> {
use crate::LinkHeader::*;
if let Ethernet2(value) = self {
Some(value)
} else {
None
}
}
/// Returns `Option::Some` containing the `LinuxSllHeader` if self has the
/// value LinuxSll. Otherwise `Option::None` is returned.
pub fn linux_sll(self) -> Option<LinuxSllHeader> {
use crate::LinkHeader::*;
if let LinuxSll(value) = self {
Some(value)
} else {
None
}
}
/// Returns `Option::Some` containing the `LinuxSllHeader` if self has the
/// value LinuxSll. Otherwise `Option::None` is returned.
pub fn mut_linux_sll(&mut self) -> Option<&mut LinuxSllHeader> {
use crate::LinkHeader::*;
if let LinuxSll(value) = self {
Some(value)
} else {
None
}
}
/// Returns the size of the link header
pub fn header_len(&self) -> usize {
use crate::LinkHeader::*;
match self {
Ethernet2(_) => Ethernet2Header::LEN,
LinuxSll(_) => LinuxSllHeader::LEN,
}
}
/// Write the link header to the given writer.
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub fn write<T: std::io::Write + Sized>(&self, writer: &mut T) -> Result<(), std::io::Error> {
use crate::LinkHeader::*;
match self {
Ethernet2(value) => value.write(writer),
LinuxSll(value) => value.write(writer),
}
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::{test_gens::*, *};
use alloc::{format, vec::Vec};
use proptest::prelude::*;
use std::io::Cursor;
proptest! {
#[test]
fn debug(
ethernet2 in ethernet_2_any(),
linux_sll in linux_sll_any(),
) {
assert_eq!(
format!("Ethernet2({:?})", ethernet2),
format!("{:?}", LinkHeader::Ethernet2(ethernet2.clone())),
);
assert_eq!(
format!("LinuxSll({:?})", linux_sll),
format!("{:?}", LinkHeader::LinuxSll(linux_sll.clone())),
);
}
}
proptest! {
#[test]
fn clone_eq(
ethernet2 in ethernet_2_any(),
linux_sll in linux_sll_any(),
) {
let values = [
LinkHeader::Ethernet2(ethernet2),
LinkHeader::LinuxSll(linux_sll),
];
for value in values {
assert_eq!(value.clone(), value);
}
}
}
proptest! {
#[test]
fn ethernet2(
ethernet2 in ethernet_2_any(),
linux_sll in linux_sll_any()
) {
assert_eq!(Some(ethernet2.clone()), LinkHeader::Ethernet2(ethernet2).ethernet2());
assert_eq!(None, LinkHeader::LinuxSll(linux_sll).ethernet2());
}
}
proptest! {
#[test]
fn mut_ethernet2(
ethernet2 in ethernet_2_any(),
linux_sll in linux_sll_any()
) {
assert_eq!(Some(&mut ethernet2.clone()), LinkHeader::Ethernet2(ethernet2).mut_ethernet2());
assert_eq!(None, LinkHeader::LinuxSll(linux_sll).mut_ethernet2());
}
}
proptest! {
#[test]
fn linux_sll(
ethernet2 in ethernet_2_any(),
linux_sll in linux_sll_any()
) {
assert_eq!(Some(linux_sll.clone()), LinkHeader::LinuxSll(linux_sll).linux_sll());
assert_eq!(None, LinkHeader::Ethernet2(ethernet2).linux_sll());
}
}
proptest! {
#[test]
fn mut_linux_sll(
ethernet2 in ethernet_2_any(),
linux_sll in linux_sll_any()
) {
assert_eq!(Some(&mut linux_sll.clone()), LinkHeader::LinuxSll(linux_sll).mut_linux_sll());
assert_eq!(None, LinkHeader::Ethernet2(ethernet2).mut_linux_sll());
}
}
proptest! {
#[test]
fn header_size(
ethernet2 in ethernet_2_any(),
linux_sll in linux_sll_any()
) {
assert_eq!(
LinkHeader::Ethernet2(ethernet2).header_len(),
Ethernet2Header::LEN
);
assert_eq!(
LinkHeader::LinuxSll(linux_sll.clone()).header_len(),
LinuxSllHeader::LEN
);
}
}
proptest! {
#[test]
fn write(
ethernet2 in ethernet_2_any(),
linux_sll in linux_sll_any()
) {
// ethernet2
{
//write
{
let result_input = {
let mut buffer = Vec::new();
ethernet2.write(&mut buffer).unwrap();
buffer
};
let result_transport = {
let mut buffer = Vec::new();
LinkHeader::Ethernet2(ethernet2.clone()).write(&mut buffer).unwrap();
buffer
};
assert_eq!(result_input, result_transport);
}
//trigger an error
{
let mut a: [u8;0] = [];
assert!(
LinkHeader::Ethernet2(ethernet2.clone())
.write(&mut Cursor::new(&mut a[..]))
.is_err()
);
}
}
// linux_sll
{
//write
{
let result_input = {
let mut buffer = Vec::new();
linux_sll.write(&mut buffer).unwrap();
buffer
};
let result_transport = {
let mut buffer = Vec::new();
LinkHeader::LinuxSll(linux_sll.clone()).write(&mut buffer).unwrap();
buffer
};
assert_eq!(result_input, result_transport);
}
//trigger an error
{
let mut a: [u8;0] = [];
assert!(
LinkHeader::LinuxSll(linux_sll.clone())
.write(&mut Cursor::new(&mut a[..]))
.is_err()
);
}
}
}
}
}