1use crate::method::Method;
4use std::fmt;
5use std::fmt::Formatter;
6use std::ops::Deref;
7
8#[derive(Copy, Clone)]
10pub enum UriContext {
11 ReqUri,
13
14 FromTo,
16
17 Contact,
19
20 Routing,
22}
23
24#[derive(Default, Copy, Clone)]
26pub struct PrintCtx<'a> {
27 pub method: Option<&'a Method>,
29 pub uri: Option<UriContext>,
30}
31
32pub struct WithPrintCtx<'a, T: ?Sized> {
36 pub ctx: PrintCtx<'a>,
37 _self: &'a T,
38}
39
40impl<T: Print + ?Sized> fmt::Display for WithPrintCtx<'_, T> {
41 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
42 Print::print(self._self, f, self.ctx)
43 }
44}
45
46impl<T> Deref for WithPrintCtx<'_, T> {
47 type Target = T;
48
49 fn deref(&self) -> &Self::Target {
50 self._self
51 }
52}
53
54pub trait AppendCtx {
56 fn print_ctx<'a>(&'a self, ctx: PrintCtx<'a>) -> WithPrintCtx<'a, Self> {
58 WithPrintCtx { ctx, _self: self }
59 }
60
61 fn default_print_ctx(&self) -> WithPrintCtx<'_, Self> {
65 self.print_ctx(Default::default())
66 }
67}
68
69impl<T: Print> AppendCtx for T {}
70
71pub trait Print {
75 fn print(&self, f: &mut fmt::Formatter<'_>, ctx: PrintCtx<'_>) -> fmt::Result;
76}
77
78impl<T: fmt::Display> Print for T {
79 fn print(&self, f: &mut fmt::Formatter<'_>, _: PrintCtx<'_>) -> fmt::Result {
80 fmt::Display::fmt(self, f)
81 }
82}
83
84pub struct BytesPrint<'b>(pub &'b [u8]);
88
89impl fmt::Debug for BytesPrint<'_> {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 for &b in self.0 {
92 if b == b'\n' {
93 writeln!(f, "\\n")?;
94 } else if b == b'\r' {
95 write!(f, "\\r")?;
96 } else if b == b'\t' {
97 write!(f, "\\t")?;
98 } else if b == b'\\' || b == b'"' {
99 write!(f, "\\{}", b as char)?;
100 } else if b == b'\0' {
101 write!(f, "\\0")?;
102 } else if (0x20..0x7f).contains(&b) {
104 write!(f, "{}", b as char)?;
105 } else {
106 write!(f, "\\x{b:02x}")?;
107 }
108 }
109 Ok(())
110 }
111}