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}