stylish_core/write.rs
1use crate::{Arguments, Formatter, Result, Style};
2
3/// A trait for writing or formatting into attributed Unicode-accepting buffers
4/// or streams.
5///
6///
7///
8/// This trait only accepts UTF-8–encoded data and is not
9/// [flushable](stylish::io::Write::flush). If you only want to accept Unicode
10/// and you don’t need flushing, you should implement this trait; otherwise you
11/// should implement [`stylish::io::Write`].
12pub trait Write {
13 /// Writes a string slice with a particular [`Style`] into this writer,
14 /// returning whether the write succeeded.
15 ///
16 /// This method can only succeed if the entire string slice was successfully
17 /// written, and this method will not return until all data has been
18 /// written or an error occurs.
19 ///
20 /// ```rust
21 /// use stylish::{Color, Foreground, Style, Write};
22 ///
23 /// let blue = Style::default().with(Foreground(Color::Blue));
24 ///
25 /// let mut s = String::new();
26 /// {
27 /// let mut output = stylish::html(&mut s);
28 /// output.write_str("water is ", Style::default())?;
29 /// output.write_str("blue", blue)?;
30 /// output.finish()?;
31 /// }
32 ///
33 /// assert_eq!(s, "water is <span style=color:blue>blue</span>");
34 /// # Ok::<(), core::fmt::Error>(())
35 /// ```
36 fn write_str(&mut self, s: &str, style: Style) -> Result;
37
38 /// Writes a [`char`] with a particular [`Style`] into this writer,
39 /// returning whether the write succeeded.
40 ///
41 /// A single [`char`] may be encoded as more than one byte. This method can
42 /// only succeed if the entire byte sequence was successfully written,
43 /// and this method will not return until all data has been written or
44 /// an error occurs.
45 ///
46 /// ```rust
47 /// use stylish::{Color, Foreground, Style, Write};
48 ///
49 /// let yellow = Style::default().with(Foreground(Color::Yellow));
50 /// let red = Style::default().with(Foreground(Color::Red));
51 ///
52 /// let mut s = String::new();
53 /// {
54 /// let mut output = stylish::html(&mut s);
55 /// output.write_char('⚠', yellow)?;
56 /// output.write_char(' ', Style::default())?;
57 /// output.write_char('⛔', red)?;
58 /// output.finish()?;
59 /// }
60 ///
61 /// assert_eq!(
62 /// s,
63 /// "<span style=color:yellow>⚠</span> <span style=color:red>⛔</span>"
64 /// );
65 /// # Ok::<(), core::fmt::Error>(())
66 /// ```
67 #[inline]
68 fn write_char(&mut self, c: char, style: Style) -> Result {
69 self.write_str(c.encode_utf8(&mut [0; 4]), style)
70 }
71
72 /// Glue for usage of the [`stylish::write!`] macro with implementors of
73 /// this trait.
74 ///
75 /// This method should generally not be invoked manually, but rather through
76 /// the [`stylish::write!`] macro itself.
77 ///
78 /// ```rust
79 /// let mut s = String::new();
80 /// {
81 /// let mut output = stylish::html(&mut s);
82 /// output.write_fmt(stylish::format_args!("{:(fg=red)}", '☎'))?;
83 /// output.finish()?;
84 /// }
85 ///
86 /// assert_eq!(s, "<span style=color:red>☎</span>");
87 /// # Ok::<(), core::fmt::Error>(())
88 /// ```
89 #[inline]
90 fn write_fmt(mut self: &mut Self, args: Arguments<'_>) -> Result {
91 Formatter::new(&mut self).write_fmt(args)
92 }
93}
94
95impl<W: Write + ?Sized> Write for &mut W {
96 fn write_str(&mut self, s: &str, style: Style) -> Result {
97 (**self).write_str(s, style)
98 }
99
100 fn write_char(&mut self, c: char, style: Style) -> Result {
101 (**self).write_char(c, style)
102 }
103
104 fn write_fmt(&mut self, args: Arguments<'_>) -> Result {
105 (**self).write_fmt(args)
106 }
107}
108
109/// Writes attributed and formatted data into a buffer.
110///
111/// This macro accepts a 'writer', a format string, and a list of arguments.
112/// Arguments will be formatted according to the specified format string and the
113/// result will be passed to the writer. The writer may be any value with a
114/// `write_fmt` method of the right signature; generally this comes from an
115/// implementation of either the [`stylish::Write`] or the
116/// [`stylish::io::Write`] trait. The macro returns whatever the `write_fmt`
117/// method returns; commonly a [`core::fmt::Result`], or a [`std::io::Result`].
118///
119/// See [`stylish`] for more information on the format string syntax.
120///
121/// # Examples
122///
123/// ```rust
124/// let mut w = stylish::html(String::new());
125///
126/// stylish::write!(&mut w, "test")?;
127/// stylish::write!(&mut w, "formatted {:(fg=yellow)}", "arguments")?;
128///
129/// assert_eq!(
130/// w.finish()?,
131/// "testformatted <span style=color:yellow>arguments</span>"
132/// );
133/// # Ok::<(), core::fmt::Error>(())
134/// ```
135#[macro_export]
136macro_rules! write {
137 ($dst:expr, $($arg:tt)*) => {
138 $dst.write_fmt($crate::format_args!($($arg)*))
139 };
140}
141
142/// Write attributed and formatted data into a buffer, with a newline appended.
143///
144/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`)
145/// alone (no additional CARRIAGE RETURN (`\r`/`U+000D`).
146///
147/// For more information, see [`stylish::write!`]. For information on the format
148/// string syntax, see [`stylish`].
149///
150/// # Examples
151///
152/// ```rust
153/// let mut w = stylish::html(String::new());
154///
155/// stylish::writeln!(&mut w)?;
156/// stylish::writeln!(&mut w, "test")?;
157/// stylish::writeln!(&mut w, "formatted {:(fg=yellow)}", "arguments")?;
158///
159/// assert_eq!(w.finish()?, "\ntest\nformatted <span style=color:yellow>arguments</span>\n");
160/// # Ok::<(), core::fmt::Error>(())
161#[macro_export]
162macro_rules! writeln {
163 ($dst:expr $(,)?) => {
164 $crate::write!($dst, "\n")
165 };
166 ($dst:expr, $($arg:tt)*) => {
167 $dst.write_fmt($crate::𓀄::format_args_nl!(crate=$crate, $($arg)*))
168 };
169}