tracer.rs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. use {Error, Result};
  2. use wire::pretty_print::{PrettyPrint, PrettyPrinter};
  3. use super::{DeviceLimits, Device};
  4. /// A tracer device.
  5. ///
  6. /// A tracer is a device that pretty prints all packets traversing it
  7. /// using the provided writer function, and then passes them to another
  8. /// device.
  9. pub struct Tracer<D: Device, P: PrettyPrint> {
  10. inner: D,
  11. writer: fn(u64, PrettyPrinter<P>)
  12. }
  13. impl<D: Device, P: PrettyPrint> Tracer<D, P> {
  14. /// Create a tracer device.
  15. pub fn new(inner: D, writer: fn(timestamp: u64, printer: PrettyPrinter<P>)) -> Tracer<D, P> {
  16. Tracer {
  17. inner: inner,
  18. writer: writer
  19. }
  20. }
  21. /// Return the underlying device, consuming the tracer.
  22. pub fn into_inner(self) -> D {
  23. self.inner
  24. }
  25. }
  26. impl<D: Device, P: PrettyPrint> Device for Tracer<D, P> {
  27. type RxBuffer = D::RxBuffer;
  28. type TxBuffer = TxBuffer<D::TxBuffer, P>;
  29. fn limits(&self) -> DeviceLimits { self.inner.limits() }
  30. fn receive(&mut self, timestamp: u64) -> Result<Self::RxBuffer> {
  31. let buffer = self.inner.receive(timestamp)?;
  32. (self.writer)(timestamp, PrettyPrinter::<P>::new("<- ", &buffer));
  33. Ok(buffer)
  34. }
  35. fn transmit(&mut self, timestamp: u64, length: usize) -> Result<Self::TxBuffer> {
  36. let buffer = self.inner.transmit(timestamp, length)?;
  37. Ok(TxBuffer { buffer, timestamp, writer: self.writer })
  38. }
  39. }
  40. #[doc(hidden)]
  41. pub struct TxBuffer<B: AsRef<[u8]> + AsMut<[u8]>, P: PrettyPrint> {
  42. buffer: B,
  43. timestamp: u64,
  44. writer: fn(u64, PrettyPrinter<P>)
  45. }
  46. impl<B: AsRef<[u8]> + AsMut<[u8]>, P: PrettyPrint> AsRef<[u8]> for TxBuffer<B, P> {
  47. fn as_ref(&self) -> &[u8] { self.buffer.as_ref() }
  48. }
  49. impl<B: AsRef<[u8]> + AsMut<[u8]>, P: PrettyPrint> AsMut<[u8]> for TxBuffer<B, P> {
  50. fn as_mut(&mut self) -> &mut [u8] { self.buffer.as_mut() }
  51. }
  52. impl<B: AsRef<[u8]> + AsMut<[u8]>, P: PrettyPrint> Drop for TxBuffer<B, P> {
  53. fn drop(&mut self) {
  54. (self.writer)(self.timestamp, PrettyPrinter::<P>::new("-> ", &self.buffer));
  55. }
  56. }