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 { 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 { 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(&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() ); } } } } }