pub trait Formatter {
// Required methods
fn begin_line_folding(&mut self);
fn end_line_folding(&mut self);
fn push_new_boundary(&mut self);
fn write_current_boundary(&mut self);
fn pop_boundary(&mut self);
fn write_bytes(&mut self, buf: &[u8]);
fn write_fws_bytes(&mut self, buf: &[u8]);
fn write_crlf(&mut self);
fn flush(self) -> Vec<u8> ⓘ;
// Provided method
fn write_fws(&mut self) { ... }
}Expand description
An output formatter that can perform line folding and compute multipart boundaries.
The Formatter API is (unfortunately) quite imperative and tricky to use.
At a high level, the trickiness comes from two aspects: formatter modes and
multipart boundaries.
§Formatter modes
A Formatter can switch between two modes: a “line folding” mode
(for writing email headers) or a “direct” mode (for writing email bodies).
Initially, a newly created Formatter is in “direct” mode. Switching to
and out of “line folding” mode is done using the begin_line_folding and
end_line_folding functions.
Depending on the mode, some functions of the API cannot be called or come with extra usage restrictions, including basic text-printing functions. (See the per-function documentation for more details.)
§Multipart boundaries
When in “direct” mode, a Formatter can generate and output multipart
boundaries. These are randomly generated to (probabilistically) ensure that
they do not clash with the rest of the output.
A boundary can be “registered” using push_new_boundary, then printed to
the output using write_current_boundary. Finally, the boundary should be
discarded when the corresponding multipart body ends, with pop_boundary.
Because multipart data can be nested, it is possible to have several
“active” boundaries at a given time. However, boundary-related functions
must be called in a way that is “well-bracketed”: conceptually, a
Formatter maintains a stack of active boundaries, only the boundary on the
top of the stack can be written to the output, and push_new_boundary and
pop_boundary must be used in a well-bracketed fashion. (See the
per-function documentation for more details.)
§Writing to the formatter
Data can be written to the output using the following functions:
write_fws_bytesandwrite_fwsoutput white space; in “line folding” mode, it can be used for folding;write_bytesoutputs text; in “line folding” mode, it cannot be used for folding;write_crlfoutputs a line break;write_current_boundaryoutputs the boundary at the top of the boundary stack.
All other functions of the API modify the internal state of the Formatter but
do not produce output.
In “line folding” mode, write_ functions must obey additional requirements:
- A line must never start with whitespace. This includes both whitespace
written using
write_bytesorwrite_fws. - Text written with
write_bytesmust never contain CRLF. /!\ Successive calls towrite_bytesthat result in a CRLF when concatenated are also forbidden! /!\
In exchange, in line folding mode, a Formatter provides the following guarantees:
- does not output “folds” that contain only folding whitespace;
- maximizes the length of folds within the line limit;
- keeps folds under the line limit, unless there is no space to fold on; in that case, fold as soon as possible after the line limit.
Note that the line limit (if any) is determined by each Formatter implementation.
Required Methods§
Sourcefn begin_line_folding(&mut self)
fn begin_line_folding(&mut self)
Switches the Formatter mode to “line folding”. The Formatter
must be currently in “direct” mode.
Sourcefn end_line_folding(&mut self)
fn end_line_folding(&mut self)
Switches the Formatter mode to “direct”. The Formatter must
be currently in “line folding” mode.
Sourcefn push_new_boundary(&mut self)
fn push_new_boundary(&mut self)
Registers a new boundary. This pushes the boundary on top of the internal “boundary stack”.
Sourcefn write_current_boundary(&mut self)
fn write_current_boundary(&mut self)
Write the current declared boundary to the output (the one on top of the
internal boundary stack). The Formatter can be either in “direct” or
“line folding” mode.
A boundary must have been registered previously.
Sourcefn pop_boundary(&mut self)
fn pop_boundary(&mut self)
Pop the current boundary from the top of the “boundary stack”.
Sourcefn write_bytes(&mut self, buf: &[u8])
fn write_bytes(&mut self, buf: &[u8])
Write bytes from buf; they cannot be used for line folding.
In line folding mode, buf must not contain CRLF and consecutive calls
to write_bytes must not result in CRLF being emitted in the output
(e.g. fmt.write_bytes(b"\r"); fmt.write_bytes(b"\n")).
It is fine for buf to include whitespace characters.
Sourcefn write_fws_bytes(&mut self, buf: &[u8])
fn write_fws_bytes(&mut self, buf: &[u8])
Write whitespace bytes from buf. In “line folding” mode, they can be
used for line folding.
buf must only contain whitespace characters ’ ’ and ‘\t’.
Sourcefn write_crlf(&mut self)
fn write_crlf(&mut self)
Terminate the current line, writing CRLF (“\r\n”).
Provided Methods§
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".