tracer.rs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. use Result;
  2. use wire::pretty_print::{PrettyPrint, PrettyPrinter};
  3. use phy::{self, DeviceCapabilities, 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: for<'a> Device<'a>, P: PrettyPrint> {
  10. inner: D,
  11. writer: fn(u64, PrettyPrinter<P>),
  12. }
  13. impl<D: for<'a> Device<'a>, 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 { inner, writer }
  17. }
  18. /// Return the underlying device, consuming the tracer.
  19. pub fn into_inner(self) -> D {
  20. self.inner
  21. }
  22. }
  23. impl<'a, D, P> Device<'a> for Tracer<D, P>
  24. where D: for<'b> Device<'b>,
  25. P: PrettyPrint + 'a,
  26. {
  27. type RxToken = RxToken<<D as Device<'a>>::RxToken, P>;
  28. type TxToken = TxToken<<D as Device<'a>>::TxToken, P>;
  29. fn capabilities(&self) -> DeviceCapabilities { self.inner.capabilities() }
  30. fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
  31. let &mut Self { ref mut inner, writer, .. } = self;
  32. inner.receive().map(|(rx_token, tx_token)| {
  33. let rx = RxToken { token: rx_token, writer: writer };
  34. let tx = TxToken { token: tx_token, writer: writer };
  35. (rx, tx)
  36. })
  37. }
  38. fn transmit(&'a mut self) -> Option<Self::TxToken> {
  39. let &mut Self { ref mut inner, writer } = self;
  40. inner.transmit().map(|tx_token| {
  41. TxToken { token: tx_token, writer: writer }
  42. })
  43. }
  44. }
  45. #[doc(hidden)]
  46. pub struct RxToken<Rx: phy::RxToken, P: PrettyPrint> {
  47. token: Rx,
  48. writer: fn(u64, PrettyPrinter<P>)
  49. }
  50. impl<Rx: phy::RxToken, P: PrettyPrint> phy::RxToken for RxToken<Rx, P> {
  51. fn consume<R, F>(self, timestamp: u64, f: F) -> Result<R>
  52. where F: FnOnce(&[u8]) -> Result<R>
  53. {
  54. let Self { token, writer } = self;
  55. token.consume(timestamp, |buffer| {
  56. writer(timestamp, PrettyPrinter::<P>::new("<- ", &buffer));
  57. f(buffer)
  58. })
  59. }
  60. }
  61. #[doc(hidden)]
  62. pub struct TxToken<Tx: phy::TxToken, P: PrettyPrint> {
  63. token: Tx,
  64. writer: fn(u64, PrettyPrinter<P>)
  65. }
  66. impl<Tx: phy::TxToken, P: PrettyPrint> phy::TxToken for TxToken<Tx, P> {
  67. fn consume<R, F>(self, timestamp: u64, len: usize, f: F) -> Result<R>
  68. where F: FnOnce(&mut [u8]) -> Result<R>
  69. {
  70. let Self { token, writer } = self;
  71. token.consume(timestamp, len, |buffer| {
  72. let result = f(buffer);
  73. writer(timestamp, PrettyPrinter::<P>::new("-> ", &buffer));
  74. result
  75. })
  76. }
  77. }