dejavu_runtime/display/
mod.rs

1use core::fmt::{Display, Formatter, Write};
2
3pub trait Escaper {
4    fn write_escaped<W>(&self, fmt: W, string: &str) -> core::fmt::Result
5    where
6        W: Write;
7}
8
9#[derive(Debug)]
10pub struct EscapeDisplay<E, T>
11where
12    E: Escaper,
13    T: Display,
14{
15    value: DisplayValue<T>,
16    escaper: E,
17}
18
19#[derive(Debug)]
20pub struct EscapeWriter<'a, E, W> {
21    fmt: W,
22    escaper: &'a E,
23}
24
25#[derive(Debug)]
26pub struct Escaped<'a, E>
27where
28    E: Escaper,
29{
30    string: &'a str,
31    escaper: E,
32}
33
34impl<E, T> EscapeDisplay<E, T>
35where
36    E: Escaper,
37    T: Display,
38{
39    pub fn dangerous(value: T, escaper: E) -> Self {
40        Self { value: DisplayValue::Unsafe(value), escaper }
41    }
42
43    pub fn safe(value: T, escaper: E) -> Self {
44        Self { value: DisplayValue::Safe(value), escaper }
45    }
46
47    #[must_use]
48    pub fn mark_safe(mut self) -> EscapeDisplay<E, T> {
49        self.value = match self.value {
50            DisplayValue::Unsafe(t) => DisplayValue::Safe(t),
51            _ => self.value,
52        };
53        self
54    }
55}
56
57impl<E, T> Display for EscapeDisplay<E, T>
58where
59    E: Escaper,
60    T: Display,
61{
62    fn fmt(&self, fmt: &mut Formatter<'_>) -> core::fmt::Result {
63        match self.value {
64            DisplayValue::Unsafe(ref t) => write!(EscapeWriter { fmt, escaper: &self.escaper }, "{t}"),
65            DisplayValue::Safe(ref t) => t.fmt(fmt),
66        }
67    }
68}
69
70impl<E, W> Write for EscapeWriter<'_, E, W>
71where
72    W: Write,
73    E: Escaper,
74{
75    fn write_str(&mut self, s: &str) -> core::fmt::Result {
76        self.escaper.write_escaped(&mut self.fmt, s)
77    }
78}
79
80pub fn escape<E>(string: &str, escaper: E) -> Escaped<'_, E>
81where
82    E: Escaper,
83{
84    Escaped { string, escaper }
85}
86
87impl<E> Display for Escaped<'_, E>
88where
89    E: Escaper,
90{
91    fn fmt(&self, fmt: &mut Formatter<'_>) -> core::fmt::Result {
92        self.escaper.write_escaped(fmt, self.string)
93    }
94}
95
96#[derive(Debug, PartialEq)]
97enum DisplayValue<T>
98where
99    T: Display,
100{
101    Safe(T),
102    Unsafe(T),
103}