pub struct Formatter { /* private fields */ }Expand description
Formats many TypeScript sources on one thread, reusing its allocations from one source to the next.
format() allocates a fresh AST arena and a fresh doc arena for every
call and drops both before returning. A Formatter owns the pair and rewinds them
instead: each rewind keeps the largest block it has grown, so after the first few
sources the work allocates almost nothing new — the shape of a driver that formats a
directory, or an editor that formats on every save. The output is exactly
format()’s (and format_with_goal’s) for
the same source.
The arenas rewind at the start of every call, so nothing one call leaves behind
reaches the next — including a call that never returned because it panicked and the
panic was caught: the next call starts from a clean arena all the same. The AST arena
is rewound once more as each call returns, which releases every block but the largest
while the Formatter sits idle.
Catching that panic takes std::panic::AssertUnwindSafe around the call — a closure
borrowing the Formatter mutably is not UnwindSafe — and the
rewind is what makes the assertion sound.
A Formatter is Send, so it can move to (or be created on) a worker thread, but
not Sync: give each thread its own.
use tsv_ts::{Formatter, Goal};
let mut formatter = Formatter::new();
for source in ["const x=42;", "let y = [1,2]"] {
let formatted = formatter.format(source)?;
assert_eq!(formatted, tsv_ts::format(source)?);
}
assert!(formatter.format_with_goal("with (a) b;", Goal::Module).is_err());
assert_eq!(formatter.format("with (a) b;")?, "with (a) b;\n");