use Error; use wire::pretty_print::{PrettyPrint, PrettyPrinter}; use super::{DeviceLimits, Device}; /// A tracer device. /// /// A tracer is a device that prints all packets traversing it /// to the standard output, and delegates to another device otherwise. pub struct Tracer { lower: T, writer: fn(PrettyPrinter) } impl Tracer { /// Create a tracer device. pub fn new(lower: T, writer: fn(PrettyPrinter)) -> Tracer { Tracer { lower: lower, writer: writer } } /// Create a tracer device, printing to standard output. #[cfg(feature = "std")] pub fn new_stdout(lower: T) -> Tracer { fn writer(printer: PrettyPrinter) { print!("{}", printer) } Tracer { lower: lower, writer: writer } } /// Return the underlying device, consuming the tracer. pub fn into_lower(self) -> T { self.lower } } impl Device for Tracer { type RxBuffer = T::RxBuffer; type TxBuffer = TxBuffer; fn limits(&self) -> DeviceLimits { self.lower.limits() } fn receive(&mut self) -> Result { let buffer = try!(self.lower.receive()); (self.writer)(PrettyPrinter::::new("<- ", &buffer)); Ok(buffer) } fn transmit(&mut self, length: usize) -> Result { let buffer = try!(self.lower.transmit(length)); Ok(TxBuffer { buffer: buffer, writer: self.writer }) } } #[doc(hidden)] pub struct TxBuffer, U: PrettyPrint> { buffer: T, writer: fn(PrettyPrinter) } impl, U: PrettyPrint> AsRef<[u8]> for TxBuffer { fn as_ref(&self) -> &[u8] { self.buffer.as_ref() } } impl + AsMut<[u8]>, U: PrettyPrint> AsMut<[u8]> for TxBuffer { fn as_mut(&mut self) -> &mut [u8] { self.buffer.as_mut() } } impl, U: PrettyPrint> Drop for TxBuffer { fn drop(&mut self) { (self.writer)(PrettyPrinter::::new("-> ", &self.buffer)); } }