mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-28 04:45:01 +00:00
Introduce Token element (#7048)
This commit is contained in:
parent
2f3a950f6f
commit
c05e4628b1
78 changed files with 733 additions and 723 deletions
|
@ -70,7 +70,7 @@ impl<'fmt, Context> Argument<'fmt, Context> {
|
|||
///
|
||||
/// # fn main() -> FormatResult<()> {
|
||||
/// let formatted = format!(SimpleFormatContext::default(), [
|
||||
/// format_args!(text("a"), space(), text("b"))
|
||||
/// format_args!(token("a"), space(), token("b"))
|
||||
/// ])?;
|
||||
///
|
||||
/// assert_eq!("a b", formatted.print()?.as_code());
|
||||
|
@ -135,11 +135,11 @@ mod tests {
|
|||
write!(
|
||||
&mut buffer,
|
||||
[
|
||||
text("function"),
|
||||
token("function"),
|
||||
space(),
|
||||
text("a"),
|
||||
token("a"),
|
||||
space(),
|
||||
group(&format_args!(text("("), text(")")))
|
||||
group(&format_args!(token("("), token(")")))
|
||||
]
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -147,14 +147,14 @@ mod tests {
|
|||
assert_eq!(
|
||||
buffer.into_vec(),
|
||||
vec![
|
||||
FormatElement::StaticText { text: "function" },
|
||||
FormatElement::Token { text: "function" },
|
||||
FormatElement::Space,
|
||||
FormatElement::StaticText { text: "a" },
|
||||
FormatElement::Token { text: "a" },
|
||||
FormatElement::Space,
|
||||
// Group
|
||||
FormatElement::Tag(Tag::StartGroup(tag::Group::new())),
|
||||
FormatElement::StaticText { text: "(" },
|
||||
FormatElement::StaticText { text: ")" },
|
||||
FormatElement::Token { text: "(" },
|
||||
FormatElement::Token { text: ")" },
|
||||
FormatElement::Tag(Tag::EndGroup)
|
||||
]
|
||||
);
|
||||
|
|
|
@ -25,9 +25,9 @@ pub trait Buffer {
|
|||
/// let mut state = FormatState::new(SimpleFormatContext::default());
|
||||
/// let mut buffer = VecBuffer::new(&mut state);
|
||||
///
|
||||
/// buffer.write_element(FormatElement::StaticText { text: "test"});
|
||||
/// buffer.write_element(FormatElement::Token { text: "test"});
|
||||
///
|
||||
/// assert_eq!(buffer.into_vec(), vec![FormatElement::StaticText { text: "test" }]);
|
||||
/// assert_eq!(buffer.into_vec(), vec![FormatElement::Token { text: "test" }]);
|
||||
/// ```
|
||||
fn write_element(&mut self, element: FormatElement);
|
||||
|
||||
|
@ -50,9 +50,9 @@ pub trait Buffer {
|
|||
/// let mut state = FormatState::new(SimpleFormatContext::default());
|
||||
/// let mut buffer = VecBuffer::new(&mut state);
|
||||
///
|
||||
/// buffer.write_fmt(format_args!(text("Hello World"))).unwrap();
|
||||
/// buffer.write_fmt(format_args!(token("Hello World"))).unwrap();
|
||||
///
|
||||
/// assert_eq!(buffer.into_vec(), vec![FormatElement::StaticText{ text: "Hello World" }]);
|
||||
/// assert_eq!(buffer.into_vec(), vec![FormatElement::Token{ text: "Hello World" }]);
|
||||
/// ```
|
||||
fn write_fmt(mut self: &mut Self, arguments: Arguments<Self::Context>) -> FormatResult<()> {
|
||||
write(&mut self, arguments)
|
||||
|
@ -316,11 +316,11 @@ where
|
|||
/// write!(
|
||||
/// buffer,
|
||||
/// [
|
||||
/// text("The next soft line or space gets replaced by a space"),
|
||||
/// token("The next soft line or space gets replaced by a space"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("and the line here"),
|
||||
/// token("and the line here"),
|
||||
/// soft_line_break(),
|
||||
/// text("is removed entirely.")
|
||||
/// token("is removed entirely.")
|
||||
/// ]
|
||||
/// )
|
||||
/// })]
|
||||
|
@ -329,10 +329,10 @@ where
|
|||
/// assert_eq!(
|
||||
/// formatted.document().as_ref(),
|
||||
/// &[
|
||||
/// FormatElement::StaticText { text: "The next soft line or space gets replaced by a space" },
|
||||
/// FormatElement::Token { text: "The next soft line or space gets replaced by a space" },
|
||||
/// FormatElement::Space,
|
||||
/// FormatElement::StaticText { text: "and the line here" },
|
||||
/// FormatElement::StaticText { text: "is removed entirely." }
|
||||
/// FormatElement::Token { text: "and the line here" },
|
||||
/// FormatElement::Token { text: "is removed entirely." }
|
||||
/// ]
|
||||
/// );
|
||||
///
|
||||
|
@ -488,19 +488,19 @@ pub trait BufferExtensions: Buffer + Sized {
|
|||
/// let formatted = format!(SimpleFormatContext::default(), [format_with(|f| {
|
||||
/// let mut recording = f.start_recording();
|
||||
///
|
||||
/// write!(recording, [text("A")])?;
|
||||
/// write!(recording, [text("B")])?;
|
||||
/// write!(recording, [token("A")])?;
|
||||
/// write!(recording, [token("B")])?;
|
||||
///
|
||||
/// write!(recording, [format_with(|f| write!(f, [text("C"), text("D")]))])?;
|
||||
/// write!(recording, [format_with(|f| write!(f, [token("C"), token("D")]))])?;
|
||||
///
|
||||
/// let recorded = recording.stop();
|
||||
/// assert_eq!(
|
||||
/// recorded.deref(),
|
||||
/// &[
|
||||
/// FormatElement::StaticText{ text: "A" },
|
||||
/// FormatElement::StaticText{ text: "B" },
|
||||
/// FormatElement::StaticText{ text: "C" },
|
||||
/// FormatElement::StaticText{ text: "D" }
|
||||
/// FormatElement::Token{ text: "A" },
|
||||
/// FormatElement::Token{ text: "B" },
|
||||
/// FormatElement::Token{ text: "C" },
|
||||
/// FormatElement::Token{ text: "D" }
|
||||
/// ]
|
||||
/// );
|
||||
///
|
||||
|
|
|
@ -26,7 +26,7 @@ use crate::{Buffer, VecBuffer};
|
|||
///
|
||||
/// # fn main() -> FormatResult<()> {
|
||||
/// let elements = format!(SimpleFormatContext::default(), [
|
||||
/// group(&format_args![text("a,"), soft_line_break(), text("b")])
|
||||
/// group(&format_args![token("a,"), soft_line_break(), token("b")])
|
||||
/// ])?;
|
||||
///
|
||||
/// assert_eq!(
|
||||
|
@ -52,9 +52,9 @@ use crate::{Buffer, VecBuffer};
|
|||
///
|
||||
/// let elements = format!(context, [
|
||||
/// group(&format_args![
|
||||
/// text("a long word,"),
|
||||
/// token("a long word,"),
|
||||
/// soft_line_break(),
|
||||
/// text("so that the group doesn't fit on a single line"),
|
||||
/// token("so that the group doesn't fit on a single line"),
|
||||
/// ])
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -83,9 +83,9 @@ pub const fn soft_line_break() -> Line {
|
|||
/// # fn main() -> FormatResult<()> {
|
||||
/// let elements = format!(SimpleFormatContext::default(), [
|
||||
/// group(&format_args![
|
||||
/// text("a,"),
|
||||
/// token("a,"),
|
||||
/// hard_line_break(),
|
||||
/// text("b"),
|
||||
/// token("b"),
|
||||
/// hard_line_break()
|
||||
/// ])
|
||||
/// ])?;
|
||||
|
@ -115,9 +115,9 @@ pub const fn hard_line_break() -> Line {
|
|||
/// let elements = format!(
|
||||
/// SimpleFormatContext::default(), [
|
||||
/// group(&format_args![
|
||||
/// text("a,"),
|
||||
/// token("a,"),
|
||||
/// empty_line(),
|
||||
/// text("b"),
|
||||
/// token("b"),
|
||||
/// empty_line()
|
||||
/// ])
|
||||
/// ])?;
|
||||
|
@ -146,9 +146,9 @@ pub const fn empty_line() -> Line {
|
|||
/// # fn main() -> FormatResult<()> {
|
||||
/// let elements = format!(SimpleFormatContext::default(), [
|
||||
/// group(&format_args![
|
||||
/// text("a,"),
|
||||
/// token("a,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("b"),
|
||||
/// token("b"),
|
||||
/// ])
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -173,9 +173,9 @@ pub const fn empty_line() -> Line {
|
|||
///
|
||||
/// let elements = format!(context, [
|
||||
/// group(&format_args![
|
||||
/// text("a long word,"),
|
||||
/// token("a long word,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("so that the group doesn't fit on a single line"),
|
||||
/// token("so that the group doesn't fit on a single line"),
|
||||
/// ])
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -215,12 +215,8 @@ impl std::fmt::Debug for Line {
|
|||
}
|
||||
}
|
||||
|
||||
/// Creates a token that gets written as is to the output. Make sure to properly escape the text if
|
||||
/// it's user generated (e.g. a string and not a language keyword).
|
||||
///
|
||||
/// # Line feeds
|
||||
/// Tokens may contain line breaks but they must use the line feeds (`\n`).
|
||||
/// The [`crate::Printer`] converts the line feed characters to the character specified in the [`crate::PrinterOptions`].
|
||||
/// Creates a token that gets written as is to the output. A token must be ASCII only and is not allowed
|
||||
/// to contain any line breaks or tab characters.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -229,7 +225,7 @@ impl std::fmt::Debug for Line {
|
|||
/// use ruff_formatter::prelude::*;
|
||||
///
|
||||
/// # fn main() -> FormatResult<()> {
|
||||
/// let elements = format!(SimpleFormatContext::default(), [text("Hello World")])?;
|
||||
/// let elements = format!(SimpleFormatContext::default(), [token("Hello World")])?;
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// "Hello World",
|
||||
|
@ -248,34 +244,38 @@ impl std::fmt::Debug for Line {
|
|||
///
|
||||
/// # fn main() -> FormatResult<()> {
|
||||
/// // the tab must be encoded as \\t to not literally print a tab character ("Hello{tab}World" vs "Hello\tWorld")
|
||||
/// let elements = format!(SimpleFormatContext::default(), [text("\"Hello\\tWorld\"")])?;
|
||||
/// let elements = format!(SimpleFormatContext::default(), [token("\"Hello\\tWorld\"")])?;
|
||||
///
|
||||
/// assert_eq!(r#""Hello\tWorld""#, elements.print()?.as_code());
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn text(text: &'static str) -> StaticText {
|
||||
debug_assert_no_newlines(text);
|
||||
pub fn token(text: &'static str) -> Token {
|
||||
debug_assert!(text.is_ascii(), "Token must be ASCII text only");
|
||||
debug_assert!(
|
||||
!text.contains(['\n', '\r', '\t']),
|
||||
"A token should not contain any newlines or tab characters"
|
||||
);
|
||||
|
||||
StaticText { text }
|
||||
Token { text }
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
pub struct StaticText {
|
||||
pub struct Token {
|
||||
text: &'static str,
|
||||
}
|
||||
|
||||
impl<Context> Format<Context> for StaticText {
|
||||
impl<Context> Format<Context> for Token {
|
||||
fn fmt(&self, f: &mut Formatter<Context>) -> FormatResult<()> {
|
||||
f.write_element(FormatElement::StaticText { text: self.text });
|
||||
f.write_element(FormatElement::Token { text: self.text });
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for StaticText {
|
||||
impl std::fmt::Debug for Token {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::write!(f, "StaticToken({})", self.text)
|
||||
std::write!(f, "Token({})", self.text)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -295,11 +295,11 @@ impl std::fmt::Debug for StaticText {
|
|||
///
|
||||
/// let elements = format!(SimpleFormatContext::default(), [
|
||||
/// source_position(TextSize::new(0)),
|
||||
/// text("\"Hello "),
|
||||
/// token("\"Hello "),
|
||||
/// source_position(TextSize::new(8)),
|
||||
/// text("'Ruff'"),
|
||||
/// token("'Ruff'"),
|
||||
/// source_position(TextSize::new(14)),
|
||||
/// text("\""),
|
||||
/// token("\""),
|
||||
/// source_position(TextSize::new(20))
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -336,25 +336,25 @@ impl<Context> Format<Context> for SourcePosition {
|
|||
|
||||
/// Creates a text from a dynamic string with its optional start-position in the source document.
|
||||
/// This is done by allocating a new string internally.
|
||||
pub fn dynamic_text(text: &str, position: Option<TextSize>) -> DynamicText {
|
||||
pub fn text(text: &str, position: Option<TextSize>) -> Text {
|
||||
debug_assert_no_newlines(text);
|
||||
|
||||
DynamicText { text, position }
|
||||
Text { text, position }
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq)]
|
||||
pub struct DynamicText<'a> {
|
||||
pub struct Text<'a> {
|
||||
text: &'a str,
|
||||
position: Option<TextSize>,
|
||||
}
|
||||
|
||||
impl<Context> Format<Context> for DynamicText<'_> {
|
||||
impl<Context> Format<Context> for Text<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<Context>) -> FormatResult<()> {
|
||||
if let Some(source_position) = self.position {
|
||||
f.write_element(FormatElement::SourcePosition(source_position));
|
||||
}
|
||||
|
||||
f.write_element(FormatElement::DynamicText {
|
||||
f.write_element(FormatElement::Text {
|
||||
text: self.text.to_string().into_boxed_str(),
|
||||
});
|
||||
|
||||
|
@ -362,9 +362,9 @@ impl<Context> Format<Context> for DynamicText<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for DynamicText<'_> {
|
||||
impl std::fmt::Debug for Text<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::write!(f, "DynamicToken({})", self.text)
|
||||
std::write!(f, "Text({})", self.text)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -446,9 +446,9 @@ fn debug_assert_no_newlines(text: &str) {
|
|||
///
|
||||
/// # fn main() -> FormatResult<()> {
|
||||
/// let elements = format!(SimpleFormatContext::default(), [
|
||||
/// text("a"),
|
||||
/// line_suffix(&text("c"), 0),
|
||||
/// text("b")
|
||||
/// token("a"),
|
||||
/// line_suffix(&token("c"), 0),
|
||||
/// token("b")
|
||||
/// ])?;
|
||||
///
|
||||
/// assert_eq!("abc", elements.print()?.as_code());
|
||||
|
@ -470,16 +470,16 @@ fn debug_assert_no_newlines(text: &str) {
|
|||
/// let elements = format!(context, [
|
||||
/// // Breaks
|
||||
/// group(&format_args![
|
||||
/// if_group_breaks(&text("(")),
|
||||
/// soft_block_indent(&format_args![text("a"), line_suffix(&text(" // a comment"), 13)]),
|
||||
/// if_group_breaks(&text(")"))
|
||||
/// if_group_breaks(&token("(")),
|
||||
/// soft_block_indent(&format_args![token("a"), line_suffix(&token(" // a comment"), 13)]),
|
||||
/// if_group_breaks(&token(")"))
|
||||
/// ]),
|
||||
///
|
||||
/// // Fits
|
||||
/// group(&format_args![
|
||||
/// if_group_breaks(&text("(")),
|
||||
/// soft_block_indent(&format_args![text("a"), line_suffix(&text(" // a comment"), 0)]),
|
||||
/// if_group_breaks(&text(")"))
|
||||
/// if_group_breaks(&token("(")),
|
||||
/// soft_block_indent(&format_args![token("a"), line_suffix(&token(" // a comment"), 0)]),
|
||||
/// if_group_breaks(&token(")"))
|
||||
/// ]),
|
||||
/// ])?;
|
||||
/// # assert_eq!("(\n\ta // a comment\n)a // a comment", elements.print()?.as_code());
|
||||
|
@ -533,11 +533,11 @@ impl<Context> std::fmt::Debug for LineSuffix<'_, Context> {
|
|||
///
|
||||
/// # fn main() -> FormatResult<()> {
|
||||
/// let elements = format!(SimpleFormatContext::default(), [
|
||||
/// text("a"),
|
||||
/// line_suffix(&text("c"), 0),
|
||||
/// text("b"),
|
||||
/// token("a"),
|
||||
/// line_suffix(&token("c"), 0),
|
||||
/// token("b"),
|
||||
/// line_suffix_boundary(),
|
||||
/// text("d")
|
||||
/// token("d")
|
||||
/// ])?;
|
||||
///
|
||||
/// assert_eq!(
|
||||
|
@ -599,7 +599,7 @@ impl<Context> Format<Context> for LineSuffixBoundary {
|
|||
/// write!(recording, [
|
||||
/// labelled(
|
||||
/// LabelId::of(MyLabels::Main),
|
||||
/// &text("'I have a label'")
|
||||
/// &token("'I have a label'")
|
||||
/// )
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -608,9 +608,9 @@ impl<Context> Format<Context> for LineSuffixBoundary {
|
|||
/// let is_labelled = recorded.first().is_some_and( |element| element.has_label(LabelId::of(MyLabels::Main)));
|
||||
///
|
||||
/// if is_labelled {
|
||||
/// write!(f, [text(" has label `Main`")])
|
||||
/// write!(f, [token(" has label `Main`")])
|
||||
/// } else {
|
||||
/// write!(f, [text(" doesn't have label `Main`")])
|
||||
/// write!(f, [token(" doesn't have label `Main`")])
|
||||
/// }
|
||||
/// })]
|
||||
/// )?;
|
||||
|
@ -670,7 +670,7 @@ impl<Context> std::fmt::Debug for FormatLabelled<'_, Context> {
|
|||
///
|
||||
/// # fn main() -> FormatResult<()> {
|
||||
/// // the tab must be encoded as \\t to not literally print a tab character ("Hello{tab}World" vs "Hello\tWorld")
|
||||
/// let elements = format!(SimpleFormatContext::default(), [text("a"), space(), text("b")])?;
|
||||
/// let elements = format!(SimpleFormatContext::default(), [token("a"), space(), token("b")])?;
|
||||
///
|
||||
/// assert_eq!("a b", elements.print()?.as_code());
|
||||
/// # Ok(())
|
||||
|
@ -708,16 +708,16 @@ impl<Context> Format<Context> for Space {
|
|||
///
|
||||
/// # fn main() -> FormatResult<()> {
|
||||
/// let block = format!(SimpleFormatContext::default(), [
|
||||
/// text("switch {"),
|
||||
/// token("switch {"),
|
||||
/// block_indent(&format_args![
|
||||
/// text("default:"),
|
||||
/// token("default:"),
|
||||
/// indent(&format_args![
|
||||
/// // this is where we want to use a
|
||||
/// hard_line_break(),
|
||||
/// text("break;"),
|
||||
/// token("break;"),
|
||||
/// ])
|
||||
/// ]),
|
||||
/// text("}"),
|
||||
/// token("}"),
|
||||
/// ])?;
|
||||
///
|
||||
/// assert_eq!(
|
||||
|
@ -772,22 +772,22 @@ impl<Context> std::fmt::Debug for Indent<'_, Context> {
|
|||
///
|
||||
/// # fn main() -> FormatResult<()> {
|
||||
/// let block = format!(SimpleFormatContext::default(), [
|
||||
/// text("root"),
|
||||
/// token("root"),
|
||||
/// align(2, &format_args![
|
||||
/// hard_line_break(),
|
||||
/// text("aligned"),
|
||||
/// token("aligned"),
|
||||
/// dedent(&format_args![
|
||||
/// hard_line_break(),
|
||||
/// text("not aligned"),
|
||||
/// token("not aligned"),
|
||||
/// ]),
|
||||
/// dedent(&indent(&format_args![
|
||||
/// hard_line_break(),
|
||||
/// text("Indented, not aligned")
|
||||
/// token("Indented, not aligned")
|
||||
/// ]))
|
||||
/// ]),
|
||||
/// dedent(&format_args![
|
||||
/// hard_line_break(),
|
||||
/// text("Dedent on root level is a no-op.")
|
||||
/// token("Dedent on root level is a no-op.")
|
||||
/// ])
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -841,23 +841,23 @@ impl<Context> std::fmt::Debug for Dedent<'_, Context> {
|
|||
///
|
||||
/// # fn main() -> FormatResult<()> {
|
||||
/// let block = format!(SimpleFormatContext::default(), [
|
||||
/// text("root"),
|
||||
/// token("root"),
|
||||
/// indent(&format_args![
|
||||
/// hard_line_break(),
|
||||
/// text("indent level 1"),
|
||||
/// token("indent level 1"),
|
||||
/// indent(&format_args![
|
||||
/// hard_line_break(),
|
||||
/// text("indent level 2"),
|
||||
/// token("indent level 2"),
|
||||
/// align(2, &format_args![
|
||||
/// hard_line_break(),
|
||||
/// text("two space align"),
|
||||
/// token("two space align"),
|
||||
/// dedent_to_root(&format_args![
|
||||
/// hard_line_break(),
|
||||
/// text("starts at the beginning of the line")
|
||||
/// token("starts at the beginning of the line")
|
||||
/// ]),
|
||||
/// ]),
|
||||
/// hard_line_break(),
|
||||
/// text("end indent level 2"),
|
||||
/// token("end indent level 2"),
|
||||
/// ])
|
||||
/// ]),
|
||||
/// ])?;
|
||||
|
@ -903,24 +903,24 @@ where
|
|||
///
|
||||
/// # fn main() -> FormatResult<()> {
|
||||
/// let block = format!(SimpleFormatContext::default(), [
|
||||
/// text("a"),
|
||||
/// token("a"),
|
||||
/// hard_line_break(),
|
||||
/// text("?"),
|
||||
/// token("?"),
|
||||
/// space(),
|
||||
/// align(2, &format_args![
|
||||
/// text("function () {"),
|
||||
/// token("function () {"),
|
||||
/// hard_line_break(),
|
||||
/// text("}"),
|
||||
/// token("}"),
|
||||
/// ]),
|
||||
/// hard_line_break(),
|
||||
/// text(":"),
|
||||
/// token(":"),
|
||||
/// space(),
|
||||
/// align(2, &format_args![
|
||||
/// text("function () {"),
|
||||
/// block_indent(&text("console.log('test');")),
|
||||
/// text("}"),
|
||||
/// token("function () {"),
|
||||
/// block_indent(&token("console.log('test');")),
|
||||
/// token("}"),
|
||||
/// ]),
|
||||
/// text(";")
|
||||
/// token(";")
|
||||
/// ])?;
|
||||
///
|
||||
/// assert_eq!(
|
||||
|
@ -953,24 +953,24 @@ where
|
|||
/// });
|
||||
///
|
||||
/// let block = format!(context, [
|
||||
/// text("a"),
|
||||
/// token("a"),
|
||||
/// hard_line_break(),
|
||||
/// text("?"),
|
||||
/// token("?"),
|
||||
/// space(),
|
||||
/// align(2, &format_args![
|
||||
/// text("function () {"),
|
||||
/// token("function () {"),
|
||||
/// hard_line_break(),
|
||||
/// text("}"),
|
||||
/// token("}"),
|
||||
/// ]),
|
||||
/// hard_line_break(),
|
||||
/// text(":"),
|
||||
/// token(":"),
|
||||
/// space(),
|
||||
/// align(2, &format_args![
|
||||
/// text("function () {"),
|
||||
/// block_indent(&text("console.log('test');")),
|
||||
/// text("}"),
|
||||
/// token("function () {"),
|
||||
/// block_indent(&token("console.log('test');")),
|
||||
/// token("}"),
|
||||
/// ]),
|
||||
/// text(";")
|
||||
/// token(";")
|
||||
/// ])?;
|
||||
///
|
||||
/// assert_eq!(
|
||||
|
@ -1038,13 +1038,13 @@ impl<Context> std::fmt::Debug for Align<'_, Context> {
|
|||
/// let block = format![
|
||||
/// SimpleFormatContext::default(),
|
||||
/// [
|
||||
/// text("{"),
|
||||
/// token("{"),
|
||||
/// block_indent(&format_args![
|
||||
/// text("let a = 10;"),
|
||||
/// token("let a = 10;"),
|
||||
/// hard_line_break(),
|
||||
/// text("let c = a + 5;"),
|
||||
/// token("let c = a + 5;"),
|
||||
/// ]),
|
||||
/// text("}"),
|
||||
/// token("}"),
|
||||
/// ]
|
||||
/// ]?;
|
||||
///
|
||||
|
@ -1083,13 +1083,13 @@ pub fn block_indent<Context>(content: &impl Format<Context>) -> BlockIndent<Cont
|
|||
///
|
||||
/// let elements = format!(context, [
|
||||
/// group(&format_args![
|
||||
/// text("["),
|
||||
/// token("["),
|
||||
/// soft_block_indent(&format_args![
|
||||
/// text("'First string',"),
|
||||
/// token("'First string',"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("'second string',"),
|
||||
/// token("'second string',"),
|
||||
/// ]),
|
||||
/// text("]"),
|
||||
/// token("]"),
|
||||
/// ])
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -1109,13 +1109,13 @@ pub fn block_indent<Context>(content: &impl Format<Context>) -> BlockIndent<Cont
|
|||
/// # fn main() -> FormatResult<()> {
|
||||
/// let elements = format!(SimpleFormatContext::default(), [
|
||||
/// group(&format_args![
|
||||
/// text("["),
|
||||
/// token("["),
|
||||
/// soft_block_indent(&format_args![
|
||||
/// text("5,"),
|
||||
/// token("5,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("10"),
|
||||
/// token("10"),
|
||||
/// ]),
|
||||
/// text("]"),
|
||||
/// token("]"),
|
||||
/// ])
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -1157,15 +1157,15 @@ pub fn soft_block_indent<Context>(content: &impl Format<Context>) -> BlockIndent
|
|||
///
|
||||
/// let elements = format!(context, [
|
||||
/// group(&format_args![
|
||||
/// text("name"),
|
||||
/// token("name"),
|
||||
/// space(),
|
||||
/// text("="),
|
||||
/// token("="),
|
||||
/// soft_line_indent_or_space(&format_args![
|
||||
/// text("firstName"),
|
||||
/// token("firstName"),
|
||||
/// space(),
|
||||
/// text("+"),
|
||||
/// token("+"),
|
||||
/// space(),
|
||||
/// text("lastName"),
|
||||
/// token("lastName"),
|
||||
/// ]),
|
||||
/// ])
|
||||
/// ])?;
|
||||
|
@ -1186,10 +1186,10 @@ pub fn soft_block_indent<Context>(content: &impl Format<Context>) -> BlockIndent
|
|||
/// # fn main() -> FormatResult<()> {
|
||||
/// let elements = format!(SimpleFormatContext::default(), [
|
||||
/// group(&format_args![
|
||||
/// text("a"),
|
||||
/// token("a"),
|
||||
/// space(),
|
||||
/// text("="),
|
||||
/// soft_line_indent_or_space(&text("10")),
|
||||
/// token("="),
|
||||
/// soft_line_indent_or_space(&token("10")),
|
||||
/// ])
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -1289,14 +1289,14 @@ impl<Context> std::fmt::Debug for BlockIndent<'_, Context> {
|
|||
///
|
||||
/// let elements = format!(context, [
|
||||
/// group(&format_args![
|
||||
/// text("{"),
|
||||
/// token("{"),
|
||||
/// soft_space_or_block_indent(&format_args![
|
||||
/// text("aPropertyThatExceeds"),
|
||||
/// text(":"),
|
||||
/// token("aPropertyThatExceeds"),
|
||||
/// token(":"),
|
||||
/// space(),
|
||||
/// text("'line width'"),
|
||||
/// token("'line width'"),
|
||||
/// ]),
|
||||
/// text("}")
|
||||
/// token("}")
|
||||
/// ])
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -1316,14 +1316,14 @@ impl<Context> std::fmt::Debug for BlockIndent<'_, Context> {
|
|||
/// # fn main() -> FormatResult<()> {
|
||||
/// let elements = format!(SimpleFormatContext::default(), [
|
||||
/// group(&format_args![
|
||||
/// text("{"),
|
||||
/// token("{"),
|
||||
/// soft_space_or_block_indent(&format_args![
|
||||
/// text("a"),
|
||||
/// text(":"),
|
||||
/// token("a"),
|
||||
/// token(":"),
|
||||
/// space(),
|
||||
/// text("5"),
|
||||
/// token("5"),
|
||||
/// ]),
|
||||
/// text("}")
|
||||
/// token("}")
|
||||
/// ])
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -1361,15 +1361,15 @@ pub fn soft_space_or_block_indent<Context>(content: &impl Format<Context>) -> Bl
|
|||
/// # fn main() -> FormatResult<()> {
|
||||
/// let elements = format!(SimpleFormatContext::default(), [
|
||||
/// group(&format_args![
|
||||
/// text("["),
|
||||
/// token("["),
|
||||
/// soft_block_indent(&format_args![
|
||||
/// text("1,"),
|
||||
/// token("1,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("2,"),
|
||||
/// token("2,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("3"),
|
||||
/// token("3"),
|
||||
/// ]),
|
||||
/// text("]"),
|
||||
/// token("]"),
|
||||
/// ])
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -1394,15 +1394,15 @@ pub fn soft_space_or_block_indent<Context>(content: &impl Format<Context>) -> Bl
|
|||
///
|
||||
/// let elements = format!(context, [
|
||||
/// group(&format_args![
|
||||
/// text("["),
|
||||
/// token("["),
|
||||
/// soft_block_indent(&format_args![
|
||||
/// text("'Good morning! How are you today?',"),
|
||||
/// token("'Good morning! How are you today?',"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("2,"),
|
||||
/// token("2,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("3"),
|
||||
/// token("3"),
|
||||
/// ]),
|
||||
/// text("]"),
|
||||
/// token("]"),
|
||||
/// ])
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -1495,37 +1495,37 @@ impl<Context> std::fmt::Debug for Group<'_, Context> {
|
|||
/// let content = format_with(|f| {
|
||||
/// let parentheses_id = f.group_id("parentheses");
|
||||
/// group(&format_args![
|
||||
/// if_group_breaks(&text("(")),
|
||||
/// if_group_breaks(&token("(")),
|
||||
/// indent_if_group_breaks(&format_args![
|
||||
/// soft_line_break(),
|
||||
/// conditional_group(&format_args![
|
||||
/// text("'aaaaaaa'"),
|
||||
/// token("'aaaaaaa'"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("+"),
|
||||
/// token("+"),
|
||||
/// space(),
|
||||
/// fits_expanded(&conditional_group(&format_args![
|
||||
/// text("["),
|
||||
/// token("["),
|
||||
/// soft_block_indent(&format_args![
|
||||
/// text("'Good morning!',"),
|
||||
/// token("'Good morning!',"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("'How are you?'"),
|
||||
/// token("'How are you?'"),
|
||||
/// ]),
|
||||
/// text("]"),
|
||||
/// token("]"),
|
||||
/// ], tag::Condition::if_group_fits_on_line(parentheses_id))),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("+"),
|
||||
/// token("+"),
|
||||
/// space(),
|
||||
/// conditional_group(&format_args![
|
||||
/// text("'bbbb'"),
|
||||
/// token("'bbbb'"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("and"),
|
||||
/// token("and"),
|
||||
/// space(),
|
||||
/// text("'c'")
|
||||
/// token("'c'")
|
||||
/// ], tag::Condition::if_group_fits_on_line(parentheses_id))
|
||||
/// ], tag::Condition::if_breaks()),
|
||||
/// ], parentheses_id),
|
||||
/// soft_line_break(),
|
||||
/// if_group_breaks(&text(")"))
|
||||
/// if_group_breaks(&token(")"))
|
||||
/// ])
|
||||
/// .with_group_id(Some(parentheses_id))
|
||||
/// .fmt(f)
|
||||
|
@ -1623,16 +1623,16 @@ impl<Context> std::fmt::Debug for ConditionalGroup<'_, Context> {
|
|||
/// # fn main() -> FormatResult<()> {
|
||||
/// let elements = format!(SimpleFormatContext::default(), [
|
||||
/// group(&format_args![
|
||||
/// text("["),
|
||||
/// token("["),
|
||||
/// soft_block_indent(&format_args![
|
||||
/// text("'Good morning! How are you today?',"),
|
||||
/// token("'Good morning! How are you today?',"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("2,"),
|
||||
/// token("2,"),
|
||||
/// expand_parent(), // Forces the parent to expand
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("3"),
|
||||
/// token("3"),
|
||||
/// ]),
|
||||
/// text("]"),
|
||||
/// token("]"),
|
||||
/// ])
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -1679,16 +1679,16 @@ impl<Context> Format<Context> for ExpandParent {
|
|||
/// # fn main() -> FormatResult<()> {
|
||||
/// let elements = format!(SimpleFormatContext::default(), [
|
||||
/// group(&format_args![
|
||||
/// text("["),
|
||||
/// token("["),
|
||||
/// soft_block_indent(&format_args![
|
||||
/// text("1,"),
|
||||
/// token("1,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("2,"),
|
||||
/// token("2,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("3"),
|
||||
/// if_group_breaks(&text(","))
|
||||
/// token("3"),
|
||||
/// if_group_breaks(&token(","))
|
||||
/// ]),
|
||||
/// text("]"),
|
||||
/// token("]"),
|
||||
/// ])
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -1713,16 +1713,16 @@ impl<Context> Format<Context> for ExpandParent {
|
|||
///
|
||||
/// let elements = format!(context, [
|
||||
/// group(&format_args![
|
||||
/// text("["),
|
||||
/// token("["),
|
||||
/// soft_block_indent(&format_args![
|
||||
/// text("'A somewhat longer string to force a line break',"),
|
||||
/// token("'A somewhat longer string to force a line break',"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("2,"),
|
||||
/// token("2,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("3"),
|
||||
/// if_group_breaks(&text(","))
|
||||
/// token("3"),
|
||||
/// if_group_breaks(&token(","))
|
||||
/// ]),
|
||||
/// text("]"),
|
||||
/// token("]"),
|
||||
/// ])
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -1760,16 +1760,16 @@ where
|
|||
/// # fn main() -> FormatResult<()> {
|
||||
/// let formatted = format!(SimpleFormatContext::default(), [
|
||||
/// group(&format_args![
|
||||
/// text("["),
|
||||
/// token("["),
|
||||
/// soft_block_indent(&format_args![
|
||||
/// text("1,"),
|
||||
/// token("1,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("2,"),
|
||||
/// token("2,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("3"),
|
||||
/// if_group_fits_on_line(&text(","))
|
||||
/// token("3"),
|
||||
/// if_group_fits_on_line(&token(","))
|
||||
/// ]),
|
||||
/// text("]"),
|
||||
/// token("]"),
|
||||
/// ])
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -1794,16 +1794,16 @@ where
|
|||
///
|
||||
/// let formatted = format!(context, [
|
||||
/// group(&format_args![
|
||||
/// text("["),
|
||||
/// token("["),
|
||||
/// soft_block_indent(&format_args![
|
||||
/// text("'A somewhat longer string to force a line break',"),
|
||||
/// token("'A somewhat longer string to force a line break',"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("2,"),
|
||||
/// token("2,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("3"),
|
||||
/// if_group_fits_on_line(&text(","))
|
||||
/// token("3"),
|
||||
/// if_group_fits_on_line(&token(","))
|
||||
/// ]),
|
||||
/// text("]"),
|
||||
/// token("]"),
|
||||
/// ])
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -1860,21 +1860,21 @@ impl<Context> IfGroupBreaks<'_, Context> {
|
|||
/// write!(f, [
|
||||
/// group(
|
||||
/// &format_args![
|
||||
/// text("["),
|
||||
/// token("["),
|
||||
/// soft_block_indent(&format_with(|f| {
|
||||
/// f.fill()
|
||||
/// .entry(&soft_line_break_or_space(), &text("1,"))
|
||||
/// .entry(&soft_line_break_or_space(), &text("234568789,"))
|
||||
/// .entry(&soft_line_break_or_space(), &text("3456789,"))
|
||||
/// .entry(&soft_line_break_or_space(), &token("1,"))
|
||||
/// .entry(&soft_line_break_or_space(), &token("234568789,"))
|
||||
/// .entry(&soft_line_break_or_space(), &token("3456789,"))
|
||||
/// .entry(&soft_line_break_or_space(), &format_args!(
|
||||
/// text("["),
|
||||
/// soft_block_indent(&text("4")),
|
||||
/// text("]"),
|
||||
/// if_group_breaks(&text(",")).with_group_id(Some(group_id))
|
||||
/// token("["),
|
||||
/// soft_block_indent(&token("4")),
|
||||
/// token("]"),
|
||||
/// if_group_breaks(&token(",")).with_group_id(Some(group_id))
|
||||
/// ))
|
||||
/// .finish()
|
||||
/// })),
|
||||
/// text("]")
|
||||
/// token("]")
|
||||
/// ],
|
||||
/// ).with_group_id(Some(group_id))
|
||||
/// ])
|
||||
|
@ -1931,9 +1931,9 @@ impl<Context> std::fmt::Debug for IfGroupBreaks<'_, Context> {
|
|||
/// let id = f.group_id("head");
|
||||
///
|
||||
/// write!(f, [
|
||||
/// group(&text("Head")).with_group_id(Some(id)),
|
||||
/// if_group_breaks(&indent(&text("indented"))).with_group_id(Some(id)),
|
||||
/// if_group_fits_on_line(&text("indented")).with_group_id(Some(id))
|
||||
/// group(&token("Head")).with_group_id(Some(id)),
|
||||
/// if_group_breaks(&indent(&token("indented"))).with_group_id(Some(id)),
|
||||
/// if_group_fits_on_line(&token("indented")).with_group_id(Some(id))
|
||||
/// ])
|
||||
///
|
||||
/// # });
|
||||
|
@ -1956,8 +1956,8 @@ impl<Context> std::fmt::Debug for IfGroupBreaks<'_, Context> {
|
|||
/// let group_id = f.group_id("header");
|
||||
///
|
||||
/// write!(f, [
|
||||
/// group(&text("(aLongHeaderThatBreaksForSomeReason) =>")).with_group_id(Some(group_id)),
|
||||
/// indent_if_group_breaks(&format_args![hard_line_break(), text("a => b")], group_id)
|
||||
/// group(&token("(aLongHeaderThatBreaksForSomeReason) =>")).with_group_id(Some(group_id)),
|
||||
/// indent_if_group_breaks(&format_args![hard_line_break(), token("a => b")], group_id)
|
||||
/// ])
|
||||
/// });
|
||||
///
|
||||
|
@ -1986,8 +1986,8 @@ impl<Context> std::fmt::Debug for IfGroupBreaks<'_, Context> {
|
|||
/// let group_id = f.group_id("header");
|
||||
///
|
||||
/// write!(f, [
|
||||
/// group(&text("(aLongHeaderThatBreaksForSomeReason) =>")).with_group_id(Some(group_id)),
|
||||
/// indent_if_group_breaks(&format_args![hard_line_break(), text("a => b")], group_id)
|
||||
/// group(&token("(aLongHeaderThatBreaksForSomeReason) =>")).with_group_id(Some(group_id)),
|
||||
/// indent_if_group_breaks(&format_args![hard_line_break(), token("a => b")], group_id)
|
||||
/// ])
|
||||
/// });
|
||||
///
|
||||
|
@ -2059,17 +2059,17 @@ impl<Context> std::fmt::Debug for IndentIfGroupBreaks<'_, Context> {
|
|||
///
|
||||
/// write!(f, [
|
||||
/// group(&format_args![
|
||||
/// text("a"),
|
||||
/// token("a"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("+"),
|
||||
/// token("+"),
|
||||
/// space(),
|
||||
/// fits_expanded(&group(&format_args![
|
||||
/// text("["),
|
||||
/// token("["),
|
||||
/// soft_block_indent(&format_args![
|
||||
/// text("a,"), space(), text("# comment"), expand_parent(), soft_line_break_or_space(),
|
||||
/// text("b")
|
||||
/// token("a,"), space(), token("# comment"), expand_parent(), soft_line_break_or_space(),
|
||||
/// token("b")
|
||||
/// ]),
|
||||
/// text("]")
|
||||
/// token("]")
|
||||
/// ]))
|
||||
/// ]),
|
||||
/// ])
|
||||
|
@ -2161,17 +2161,17 @@ impl<Context, T> std::fmt::Debug for FormatWith<Context, T> {
|
|||
/// impl Format<SimpleFormatContext> for MyFormat {
|
||||
/// fn fmt(&self, f: &mut Formatter<SimpleFormatContext>) -> FormatResult<()> {
|
||||
/// write!(f, [
|
||||
/// text("("),
|
||||
/// token("("),
|
||||
/// block_indent(&format_with(|f| {
|
||||
/// let separator = space();
|
||||
/// let mut join = f.join_with(&separator);
|
||||
///
|
||||
/// for item in &self.items {
|
||||
/// join.entry(&format_with(|f| write!(f, [dynamic_text(item, None)])));
|
||||
/// join.entry(&format_with(|f| write!(f, [text(item, None)])));
|
||||
/// }
|
||||
/// join.finish()
|
||||
/// })),
|
||||
/// text(")")
|
||||
/// token(")")
|
||||
/// ])
|
||||
/// }
|
||||
/// }
|
||||
|
@ -2212,8 +2212,8 @@ where
|
|||
///
|
||||
/// struct MyFormat;
|
||||
///
|
||||
/// fn generate_values() -> impl Iterator<Item=StaticText> {
|
||||
/// vec![text("1"), text("2"), text("3"), text("4")].into_iter()
|
||||
/// fn generate_values() -> impl Iterator<Item=Token> {
|
||||
/// vec![token("1"), token("2"), token("3"), token("4")].into_iter()
|
||||
/// }
|
||||
///
|
||||
/// impl Format<SimpleFormatContext> for MyFormat {
|
||||
|
@ -2244,7 +2244,7 @@ where
|
|||
///
|
||||
/// Formatting the same value twice results in a panic.
|
||||
///
|
||||
/// ```panics
|
||||
/// ```should_panic
|
||||
/// use ruff_formatter::prelude::*;
|
||||
/// use ruff_formatter::{SimpleFormatContext, format, write, Buffer};
|
||||
/// use ruff_text_size::TextSize;
|
||||
|
@ -2252,7 +2252,7 @@ where
|
|||
/// let mut count = 0;
|
||||
///
|
||||
/// let value = format_once(|f| {
|
||||
/// write!(f, [dynamic_token(&std::format!("Formatted {count}."), TextSize::default())])
|
||||
/// write!(f, [text(&std::format!("Formatted {count}."), None)])
|
||||
/// });
|
||||
///
|
||||
/// format!(SimpleFormatContext::default(), [value]).expect("Formatting once works fine");
|
||||
|
@ -2476,54 +2476,54 @@ impl<'a, Context> BestFitting<'a, Context> {
|
|||
/// // Everything fits on a single line
|
||||
/// format_args!(
|
||||
/// group(&format_args![
|
||||
/// text("["),
|
||||
/// token("["),
|
||||
/// soft_block_indent(&format_args![
|
||||
/// text("1,"),
|
||||
/// token("1,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("2,"),
|
||||
/// token("2,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("3"),
|
||||
/// token("3"),
|
||||
/// ]),
|
||||
/// text("]")
|
||||
/// token("]")
|
||||
/// ]),
|
||||
/// space(),
|
||||
/// text("+"),
|
||||
/// token("+"),
|
||||
/// space(),
|
||||
/// text("aVeryLongIdentifier")
|
||||
/// token("aVeryLongIdentifier")
|
||||
/// ),
|
||||
///
|
||||
/// // Breaks after `[` and prints each elements on a single line
|
||||
/// // The group is necessary because the variant, by default is printed in flat mode and a
|
||||
/// // hard line break indicates that the content doesn't fit.
|
||||
/// format_args!(
|
||||
/// text("["),
|
||||
/// group(&block_indent(&format_args![text("1,"), hard_line_break(), text("2,"), hard_line_break(), text("3")])).should_expand(true),
|
||||
/// text("]"),
|
||||
/// token("["),
|
||||
/// group(&block_indent(&format_args![token("1,"), hard_line_break(), token("2,"), hard_line_break(), token("3")])).should_expand(true),
|
||||
/// token("]"),
|
||||
/// space(),
|
||||
/// text("+"),
|
||||
/// token("+"),
|
||||
/// space(),
|
||||
/// text("aVeryLongIdentifier")
|
||||
/// token("aVeryLongIdentifier")
|
||||
/// ),
|
||||
///
|
||||
/// // Adds parentheses and indents the body, breaks after the operator
|
||||
/// format_args!(
|
||||
/// text("("),
|
||||
/// token("("),
|
||||
/// block_indent(&format_args![
|
||||
/// text("["),
|
||||
/// token("["),
|
||||
/// block_indent(&format_args![
|
||||
/// text("1,"),
|
||||
/// token("1,"),
|
||||
/// hard_line_break(),
|
||||
/// text("2,"),
|
||||
/// token("2,"),
|
||||
/// hard_line_break(),
|
||||
/// text("3"),
|
||||
/// token("3"),
|
||||
/// ]),
|
||||
/// text("]"),
|
||||
/// token("]"),
|
||||
/// hard_line_break(),
|
||||
/// text("+"),
|
||||
/// token("+"),
|
||||
/// space(),
|
||||
/// text("aVeryLongIdentifier")
|
||||
/// token("aVeryLongIdentifier")
|
||||
/// ]),
|
||||
/// text(")")
|
||||
/// token(")")
|
||||
/// )
|
||||
/// ).with_mode(BestFittingMode::AllLines)
|
||||
/// ]
|
||||
|
|
|
@ -30,12 +30,11 @@ pub enum FormatElement {
|
|||
/// formatted position.
|
||||
SourcePosition(TextSize),
|
||||
|
||||
/// Token constructed by the formatter from a static string
|
||||
StaticText { text: &'static str },
|
||||
/// A ASCII only Token that contains no line breaks or tab characters.
|
||||
Token { text: &'static str },
|
||||
|
||||
/// Token constructed from the input source as a dynamic
|
||||
/// string.
|
||||
DynamicText {
|
||||
/// An arbitrary text that can contain tabs, newlines, and unicode characters.
|
||||
Text {
|
||||
/// There's no need for the text to be mutable, using `Box<str>` safes 8 bytes over `String`.
|
||||
text: Box<str>,
|
||||
},
|
||||
|
@ -72,12 +71,8 @@ impl std::fmt::Debug for FormatElement {
|
|||
FormatElement::Space => write!(fmt, "Space"),
|
||||
FormatElement::Line(mode) => fmt.debug_tuple("Line").field(mode).finish(),
|
||||
FormatElement::ExpandParent => write!(fmt, "ExpandParent"),
|
||||
FormatElement::StaticText { text } => {
|
||||
fmt.debug_tuple("StaticText").field(text).finish()
|
||||
}
|
||||
FormatElement::DynamicText { text, .. } => {
|
||||
fmt.debug_tuple("DynamicText").field(text).finish()
|
||||
}
|
||||
FormatElement::Token { text } => fmt.debug_tuple("Token").field(text).finish(),
|
||||
FormatElement::Text { text, .. } => fmt.debug_tuple("DynamicText").field(text).finish(),
|
||||
FormatElement::SourceCodeSlice {
|
||||
slice,
|
||||
contains_newlines,
|
||||
|
@ -244,8 +239,8 @@ impl FormatElement {
|
|||
matches!(
|
||||
self,
|
||||
FormatElement::SourceCodeSlice { .. }
|
||||
| FormatElement::DynamicText { .. }
|
||||
| FormatElement::StaticText { .. }
|
||||
| FormatElement::Text { .. }
|
||||
| FormatElement::Token { .. }
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -260,8 +255,8 @@ impl FormatElements for FormatElement {
|
|||
FormatElement::ExpandParent => true,
|
||||
FormatElement::Tag(Tag::StartGroup(group)) => !group.mode().is_flat(),
|
||||
FormatElement::Line(line_mode) => matches!(line_mode, LineMode::Hard | LineMode::Empty),
|
||||
FormatElement::StaticText { text } => text.contains('\n'),
|
||||
FormatElement::DynamicText { text, .. } => text.contains('\n'),
|
||||
|
||||
FormatElement::Text { text, .. } => text.contains('\n'),
|
||||
FormatElement::SourceCodeSlice {
|
||||
contains_newlines, ..
|
||||
} => *contains_newlines,
|
||||
|
@ -275,6 +270,7 @@ impl FormatElements for FormatElement {
|
|||
FormatElement::LineSuffixBoundary
|
||||
| FormatElement::Space
|
||||
| FormatElement::Tag(_)
|
||||
| FormatElement::Token { .. }
|
||||
| FormatElement::SourcePosition(_) => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,8 +104,7 @@ impl Document {
|
|||
expands = false;
|
||||
continue;
|
||||
}
|
||||
FormatElement::StaticText { text } => text.contains('\n'),
|
||||
FormatElement::DynamicText { text, .. } => text.contains('\n'),
|
||||
FormatElement::Text { text, .. } => text.contains('\n'),
|
||||
FormatElement::SourceCodeSlice {
|
||||
contains_newlines, ..
|
||||
} => *contains_newlines,
|
||||
|
@ -249,20 +248,20 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
while let Some(element) = iter.next() {
|
||||
if !first_element && !in_text && !element.is_end_tag() {
|
||||
// Write a separator between every two elements
|
||||
write!(f, [text(","), soft_line_break_or_space()])?;
|
||||
write!(f, [token(","), soft_line_break_or_space()])?;
|
||||
}
|
||||
|
||||
first_element = false;
|
||||
|
||||
match element {
|
||||
element @ (FormatElement::Space
|
||||
| FormatElement::StaticText { .. }
|
||||
| FormatElement::DynamicText { .. }
|
||||
| FormatElement::Token { .. }
|
||||
| FormatElement::Text { .. }
|
||||
| FormatElement::SourceCodeSlice { .. }) => {
|
||||
fn write_escaped(element: &FormatElement, f: &mut Formatter<IrFormatContext>) {
|
||||
let text = match element {
|
||||
FormatElement::StaticText { text } => text,
|
||||
FormatElement::DynamicText { text } => text.as_ref(),
|
||||
FormatElement::Token { text } => text,
|
||||
FormatElement::Text { text } => text.as_ref(),
|
||||
FormatElement::SourceCodeSlice { slice, .. } => {
|
||||
slice.text(f.context().source_code())
|
||||
}
|
||||
|
@ -270,7 +269,7 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
};
|
||||
|
||||
if text.contains('"') {
|
||||
f.write_element(FormatElement::DynamicText {
|
||||
f.write_element(FormatElement::Text {
|
||||
text: text.replace('"', r#"\""#).into(),
|
||||
});
|
||||
} else {
|
||||
|
@ -279,14 +278,14 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
}
|
||||
|
||||
if !in_text {
|
||||
write!(f, [text("\"")])?;
|
||||
write!(f, [token("\"")])?;
|
||||
}
|
||||
|
||||
in_text = true;
|
||||
|
||||
match element {
|
||||
FormatElement::Space => {
|
||||
write!(f, [text(" ")])?;
|
||||
write!(f, [token(" ")])?;
|
||||
}
|
||||
element if element.is_text() => {
|
||||
write_escaped(element, f);
|
||||
|
@ -297,45 +296,42 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
let is_next_text = iter.peek().is_some_and(|e| e.is_text() || e.is_space());
|
||||
|
||||
if !is_next_text {
|
||||
write!(f, [text("\"")])?;
|
||||
write!(f, [token("\"")])?;
|
||||
in_text = false;
|
||||
}
|
||||
}
|
||||
|
||||
FormatElement::Line(mode) => match mode {
|
||||
LineMode::SoftOrSpace => {
|
||||
write!(f, [text("soft_line_break_or_space")])?;
|
||||
write!(f, [token("soft_line_break_or_space")])?;
|
||||
}
|
||||
LineMode::Soft => {
|
||||
write!(f, [text("soft_line_break")])?;
|
||||
write!(f, [token("soft_line_break")])?;
|
||||
}
|
||||
LineMode::Hard => {
|
||||
write!(f, [text("hard_line_break")])?;
|
||||
write!(f, [token("hard_line_break")])?;
|
||||
}
|
||||
LineMode::Empty => {
|
||||
write!(f, [text("empty_line")])?;
|
||||
write!(f, [token("empty_line")])?;
|
||||
}
|
||||
},
|
||||
FormatElement::ExpandParent => {
|
||||
write!(f, [text("expand_parent")])?;
|
||||
write!(f, [token("expand_parent")])?;
|
||||
}
|
||||
|
||||
FormatElement::SourcePosition(position) => {
|
||||
write!(
|
||||
f,
|
||||
[dynamic_text(
|
||||
&std::format!("source_position({position:?})"),
|
||||
None
|
||||
)]
|
||||
[text(&std::format!("source_position({position:?})"), None)]
|
||||
)?;
|
||||
}
|
||||
|
||||
FormatElement::LineSuffixBoundary => {
|
||||
write!(f, [text("line_suffix_boundary")])?;
|
||||
write!(f, [token("line_suffix_boundary")])?;
|
||||
}
|
||||
|
||||
FormatElement::BestFitting { variants, mode } => {
|
||||
write!(f, [text("best_fitting([")])?;
|
||||
write!(f, [token("best_fitting([")])?;
|
||||
f.write_elements([
|
||||
FormatElement::Tag(StartIndent),
|
||||
FormatElement::Line(LineMode::Hard),
|
||||
|
@ -350,13 +346,13 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
FormatElement::Line(LineMode::Hard),
|
||||
]);
|
||||
|
||||
write!(f, [text("]")])?;
|
||||
write!(f, [token("]")])?;
|
||||
|
||||
if *mode != BestFittingMode::FirstLine {
|
||||
write!(f, [dynamic_text(&std::format!(", mode: {mode:?}"), None),])?;
|
||||
write!(f, [text(&std::format!(", mode: {mode:?}"), None),])?;
|
||||
}
|
||||
|
||||
write!(f, [text(")")])?;
|
||||
write!(f, [token(")")])?;
|
||||
}
|
||||
|
||||
FormatElement::Interned(interned) => {
|
||||
|
@ -370,7 +366,7 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
write!(
|
||||
f,
|
||||
[
|
||||
dynamic_text(&std::format!("<interned {index}>"), None),
|
||||
text(&std::format!("<interned {index}>"), None),
|
||||
space(),
|
||||
&&**interned,
|
||||
]
|
||||
|
@ -379,10 +375,7 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
Some(reference) => {
|
||||
write!(
|
||||
f,
|
||||
[dynamic_text(
|
||||
&std::format!("<ref interned *{reference}>"),
|
||||
None
|
||||
)]
|
||||
[text(&std::format!("<ref interned *{reference}>"), None)]
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
@ -401,9 +394,9 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
write!(
|
||||
f,
|
||||
[
|
||||
text("<END_TAG_WITHOUT_START<"),
|
||||
dynamic_text(&std::format!("{:?}", tag.kind()), None),
|
||||
text(">>"),
|
||||
token("<END_TAG_WITHOUT_START<"),
|
||||
text(&std::format!("{:?}", tag.kind()), None),
|
||||
token(">>"),
|
||||
]
|
||||
)?;
|
||||
first_element = false;
|
||||
|
@ -414,13 +407,13 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
f,
|
||||
[
|
||||
ContentArrayEnd,
|
||||
text(")"),
|
||||
token(")"),
|
||||
soft_line_break_or_space(),
|
||||
text("ERROR<START_END_TAG_MISMATCH<start: "),
|
||||
dynamic_text(&std::format!("{start_kind:?}"), None),
|
||||
text(", end: "),
|
||||
dynamic_text(&std::format!("{:?}", tag.kind()), None),
|
||||
text(">>")
|
||||
token("ERROR<START_END_TAG_MISMATCH<start: "),
|
||||
text(&std::format!("{start_kind:?}"), None),
|
||||
token(", end: "),
|
||||
text(&std::format!("{:?}", tag.kind()), None),
|
||||
token(">>")
|
||||
]
|
||||
)?;
|
||||
first_element = false;
|
||||
|
@ -434,7 +427,7 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
|
||||
match tag {
|
||||
StartIndent => {
|
||||
write!(f, [text("indent(")])?;
|
||||
write!(f, [token("indent(")])?;
|
||||
}
|
||||
|
||||
StartDedent(mode) => {
|
||||
|
@ -443,16 +436,16 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
DedentMode::Root => "dedentRoot",
|
||||
};
|
||||
|
||||
write!(f, [text(label), text("(")])?;
|
||||
write!(f, [token(label), token("(")])?;
|
||||
}
|
||||
|
||||
StartAlign(tag::Align(count)) => {
|
||||
write!(
|
||||
f,
|
||||
[
|
||||
text("align("),
|
||||
dynamic_text(&count.to_string(), None),
|
||||
text(","),
|
||||
token("align("),
|
||||
text(&count.to_string(), None),
|
||||
token(","),
|
||||
space(),
|
||||
]
|
||||
)?;
|
||||
|
@ -462,27 +455,27 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
write!(
|
||||
f,
|
||||
[
|
||||
text("line_suffix("),
|
||||
dynamic_text(&std::format!("{reserved_width:?}"), None),
|
||||
text(","),
|
||||
token("line_suffix("),
|
||||
text(&std::format!("{reserved_width:?}"), None),
|
||||
token(","),
|
||||
space(),
|
||||
]
|
||||
)?;
|
||||
}
|
||||
|
||||
StartVerbatim(_) => {
|
||||
write!(f, [text("verbatim(")])?;
|
||||
write!(f, [token("verbatim(")])?;
|
||||
}
|
||||
|
||||
StartGroup(group) => {
|
||||
write!(f, [text("group(")])?;
|
||||
write!(f, [token("group(")])?;
|
||||
|
||||
if let Some(group_id) = group.id() {
|
||||
write!(
|
||||
f,
|
||||
[
|
||||
dynamic_text(&std::format!("\"{group_id:?}\""), None),
|
||||
text(","),
|
||||
text(&std::format!("\"{group_id:?}\""), None),
|
||||
token(","),
|
||||
space(),
|
||||
]
|
||||
)?;
|
||||
|
@ -491,10 +484,10 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
match group.mode() {
|
||||
GroupMode::Flat => {}
|
||||
GroupMode::Expand => {
|
||||
write!(f, [text("expand: true,"), space()])?;
|
||||
write!(f, [token("expand: true,"), space()])?;
|
||||
}
|
||||
GroupMode::Propagated => {
|
||||
write!(f, [text("expand: propagated,"), space()])?;
|
||||
write!(f, [token("expand: propagated,"), space()])?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -503,10 +496,10 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
write!(
|
||||
f,
|
||||
[
|
||||
text("conditional_group(condition:"),
|
||||
token("conditional_group(condition:"),
|
||||
space(),
|
||||
group.condition(),
|
||||
text(","),
|
||||
token(","),
|
||||
space()
|
||||
]
|
||||
)?;
|
||||
|
@ -514,10 +507,10 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
match group.mode() {
|
||||
GroupMode::Flat => {}
|
||||
GroupMode::Expand => {
|
||||
write!(f, [text("expand: true,"), space()])?;
|
||||
write!(f, [token("expand: true,"), space()])?;
|
||||
}
|
||||
GroupMode::Propagated => {
|
||||
write!(f, [text("expand: propagated,"), space()])?;
|
||||
write!(f, [token("expand: propagated,"), space()])?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -526,9 +519,9 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
write!(
|
||||
f,
|
||||
[
|
||||
text("indent_if_group_breaks("),
|
||||
dynamic_text(&std::format!("\"{id:?}\""), None),
|
||||
text(","),
|
||||
token("indent_if_group_breaks("),
|
||||
text(&std::format!("\"{id:?}\""), None),
|
||||
token(","),
|
||||
space(),
|
||||
]
|
||||
)?;
|
||||
|
@ -537,10 +530,10 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
StartConditionalContent(condition) => {
|
||||
match condition.mode {
|
||||
PrintMode::Flat => {
|
||||
write!(f, [text("if_group_fits_on_line(")])?;
|
||||
write!(f, [token("if_group_fits_on_line(")])?;
|
||||
}
|
||||
PrintMode::Expanded => {
|
||||
write!(f, [text("if_group_breaks(")])?;
|
||||
write!(f, [token("if_group_breaks(")])?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -548,8 +541,8 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
write!(
|
||||
f,
|
||||
[
|
||||
dynamic_text(&std::format!("\"{group_id:?}\""), None),
|
||||
text(","),
|
||||
text(&std::format!("\"{group_id:?}\""), None),
|
||||
token(","),
|
||||
space(),
|
||||
]
|
||||
)?;
|
||||
|
@ -560,36 +553,36 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
write!(
|
||||
f,
|
||||
[
|
||||
text("label("),
|
||||
dynamic_text(&std::format!("\"{label_id:?}\""), None),
|
||||
text(","),
|
||||
token("label("),
|
||||
text(&std::format!("\"{label_id:?}\""), None),
|
||||
token(","),
|
||||
space(),
|
||||
]
|
||||
)?;
|
||||
}
|
||||
|
||||
StartFill => {
|
||||
write!(f, [text("fill(")])?;
|
||||
write!(f, [token("fill(")])?;
|
||||
}
|
||||
|
||||
StartFitsExpanded(tag::FitsExpanded {
|
||||
condition,
|
||||
propagate_expand,
|
||||
}) => {
|
||||
write!(f, [text("fits_expanded(propagate_expand:"), space()])?;
|
||||
write!(f, [token("fits_expanded(propagate_expand:"), space()])?;
|
||||
|
||||
if propagate_expand.get() {
|
||||
write!(f, [text("true")])?;
|
||||
write!(f, [token("true")])?;
|
||||
} else {
|
||||
write!(f, [text("false")])?;
|
||||
write!(f, [token("false")])?;
|
||||
}
|
||||
|
||||
write!(f, [text(","), space()])?;
|
||||
write!(f, [token(","), space()])?;
|
||||
|
||||
if let Some(condition) = condition {
|
||||
write!(
|
||||
f,
|
||||
[text("condition:"), space(), condition, text(","), space()]
|
||||
[token("condition:"), space(), condition, token(","), space()]
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
@ -611,7 +604,7 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
| EndDedent
|
||||
| EndFitsExpanded
|
||||
| EndVerbatim => {
|
||||
write!(f, [ContentArrayEnd, text(")")])?;
|
||||
write!(f, [ContentArrayEnd, token(")")])?;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -627,9 +620,9 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
f,
|
||||
[
|
||||
ContentArrayEnd,
|
||||
text(")"),
|
||||
token(")"),
|
||||
soft_line_break_or_space(),
|
||||
dynamic_text(&std::format!("<START_WITHOUT_END<{top:?}>>"), None),
|
||||
text(&std::format!("<START_WITHOUT_END<{top:?}>>"), None),
|
||||
]
|
||||
)?;
|
||||
}
|
||||
|
@ -644,7 +637,7 @@ impl Format<IrFormatContext<'_>> for ContentArrayStart {
|
|||
fn fmt(&self, f: &mut Formatter<IrFormatContext>) -> FormatResult<()> {
|
||||
use Tag::{StartGroup, StartIndent};
|
||||
|
||||
write!(f, [text("[")])?;
|
||||
write!(f, [token("[")])?;
|
||||
|
||||
f.write_elements([
|
||||
FormatElement::Tag(StartGroup(tag::Group::new())),
|
||||
|
@ -667,7 +660,7 @@ impl Format<IrFormatContext<'_>> for ContentArrayEnd {
|
|||
FormatElement::Tag(EndGroup),
|
||||
]);
|
||||
|
||||
write!(f, [text("]")])
|
||||
write!(f, [token("]")])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -767,22 +760,22 @@ impl FormatElements for [FormatElement] {
|
|||
impl Format<IrFormatContext<'_>> for Condition {
|
||||
fn fmt(&self, f: &mut Formatter<IrFormatContext>) -> FormatResult<()> {
|
||||
match (self.mode, self.group_id) {
|
||||
(PrintMode::Flat, None) => write!(f, [text("if_fits_on_line")]),
|
||||
(PrintMode::Flat, None) => write!(f, [token("if_fits_on_line")]),
|
||||
(PrintMode::Flat, Some(id)) => write!(
|
||||
f,
|
||||
[
|
||||
text("if_group_fits_on_line("),
|
||||
dynamic_text(&std::format!("\"{id:?}\""), None),
|
||||
text(")")
|
||||
token("if_group_fits_on_line("),
|
||||
text(&std::format!("\"{id:?}\""), None),
|
||||
token(")")
|
||||
]
|
||||
),
|
||||
(PrintMode::Expanded, None) => write!(f, [text("if_breaks")]),
|
||||
(PrintMode::Expanded, None) => write!(f, [token("if_breaks")]),
|
||||
(PrintMode::Expanded, Some(id)) => write!(
|
||||
f,
|
||||
[
|
||||
text("if_group_breaks("),
|
||||
dynamic_text(&std::format!("\"{id:?}\""), None),
|
||||
text(")")
|
||||
token("if_group_breaks("),
|
||||
text(&std::format!("\"{id:?}\""), None),
|
||||
token(")")
|
||||
]
|
||||
),
|
||||
}
|
||||
|
@ -805,11 +798,11 @@ mod tests {
|
|||
write!(
|
||||
f,
|
||||
[group(&format_args![
|
||||
text("("),
|
||||
token("("),
|
||||
soft_block_indent(&format_args![
|
||||
text("Some longer content"),
|
||||
token("Some longer content"),
|
||||
space(),
|
||||
text("That should ultimately break"),
|
||||
token("That should ultimately break"),
|
||||
])
|
||||
])]
|
||||
)
|
||||
|
@ -838,7 +831,7 @@ mod tests {
|
|||
fn escapes_quotes() {
|
||||
let formatted = format!(
|
||||
SimpleFormatContext::default(),
|
||||
[text(r#""""Python docstring""""#)]
|
||||
[token(r#""""Python docstring""""#)]
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -859,7 +852,7 @@ mod tests {
|
|||
write!(
|
||||
f,
|
||||
[group(&format_args![
|
||||
text("("),
|
||||
token("("),
|
||||
soft_block_indent(&format_args![
|
||||
source_text_slice(
|
||||
TextRange::at(TextSize::new(0), TextSize::new(19)),
|
||||
|
@ -899,16 +892,16 @@ mod tests {
|
|||
use Tag::*;
|
||||
|
||||
let document = Document::from(vec![
|
||||
FormatElement::StaticText { text: "[" },
|
||||
FormatElement::Token { text: "[" },
|
||||
FormatElement::Tag(StartGroup(tag::Group::new())),
|
||||
FormatElement::Tag(StartIndent),
|
||||
FormatElement::Line(LineMode::Soft),
|
||||
FormatElement::StaticText { text: "a" },
|
||||
FormatElement::Token { text: "a" },
|
||||
// Close group instead of indent
|
||||
FormatElement::Tag(EndGroup),
|
||||
FormatElement::Line(LineMode::Soft),
|
||||
FormatElement::Tag(EndIndent),
|
||||
FormatElement::StaticText { text: "]" },
|
||||
FormatElement::Token { text: "]" },
|
||||
// End tag without start
|
||||
FormatElement::Tag(EndIndent),
|
||||
// Start tag without an end
|
||||
|
|
|
@ -34,7 +34,7 @@ pub trait MemoizeFormat<Context> {
|
|||
/// let value = self.value.get();
|
||||
/// self.value.set(value + 1);
|
||||
///
|
||||
/// write!(f, [dynamic_text(&std::format!("Formatted {value} times."), None)])
|
||||
/// write!(f, [text(&std::format!("Formatted {value} times."), None)])
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
|
@ -110,9 +110,9 @@ where
|
|||
/// let current = self.value.get();
|
||||
///
|
||||
/// write!(f, [
|
||||
/// text("Count:"),
|
||||
/// token("Count:"),
|
||||
/// space(),
|
||||
/// dynamic_text(&std::format!("{current}"), None),
|
||||
/// text(&std::format!("{current}"), None),
|
||||
/// hard_line_break()
|
||||
/// ])?;
|
||||
///
|
||||
|
@ -127,9 +127,9 @@ where
|
|||
/// let counter_content = counter.inspect(f)?;
|
||||
///
|
||||
/// if counter_content.will_break() {
|
||||
/// write!(f, [text("Counter:"), block_indent(&counter)])
|
||||
/// write!(f, [token("Counter:"), block_indent(&counter)])
|
||||
/// } else {
|
||||
/// write!(f, [text("Counter:"), counter])
|
||||
/// write!(f, [token("Counter:"), counter])
|
||||
/// }?;
|
||||
///
|
||||
/// write!(f, [counter])
|
||||
|
|
|
@ -52,11 +52,11 @@ impl<'buf, Context> Formatter<'buf, Context> {
|
|||
/// # fn main() -> FormatResult<()> {
|
||||
/// let formatted = format!(SimpleFormatContext::default(), [format_with(|f| {
|
||||
/// f.join()
|
||||
/// .entry(&text("a"))
|
||||
/// .entry(&token("a"))
|
||||
/// .entry(&space())
|
||||
/// .entry(&text("+"))
|
||||
/// .entry(&token("+"))
|
||||
/// .entry(&space())
|
||||
/// .entry(&text("b"))
|
||||
/// .entry(&token("b"))
|
||||
/// .finish()
|
||||
/// })])?;
|
||||
///
|
||||
|
@ -83,11 +83,11 @@ impl<'buf, Context> Formatter<'buf, Context> {
|
|||
///
|
||||
/// # fn main() -> FormatResult<()> {
|
||||
/// let formatted = format!(SimpleFormatContext::default(), [format_with(|f| {
|
||||
/// f.join_with(&format_args!(text(","), space()))
|
||||
/// .entry(&text("1"))
|
||||
/// .entry(&text("2"))
|
||||
/// .entry(&text("3"))
|
||||
/// .entry(&text("4"))
|
||||
/// f.join_with(&format_args!(token(","), space()))
|
||||
/// .entry(&token("1"))
|
||||
/// .entry(&token("2"))
|
||||
/// .entry(&token("3"))
|
||||
/// .entry(&token("4"))
|
||||
/// .finish()
|
||||
/// })])?;
|
||||
///
|
||||
|
@ -121,10 +121,10 @@ impl<'buf, Context> Formatter<'buf, Context> {
|
|||
/// # fn main() -> FormatResult<()> {
|
||||
/// let formatted = format!(SimpleFormatContext::default(), [format_with(|f| {
|
||||
/// f.fill()
|
||||
/// .entry(&soft_line_break_or_space(), &text("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
|
||||
/// .entry(&soft_line_break_or_space(), &text("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"))
|
||||
/// .entry(&soft_line_break_or_space(), &text("cccccccccccccccccccccccccccccc"))
|
||||
/// .entry(&soft_line_break_or_space(), &text("dddddddddddddddddddddddddddddd"))
|
||||
/// .entry(&soft_line_break_or_space(), &token("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
|
||||
/// .entry(&soft_line_break_or_space(), &token("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"))
|
||||
/// .entry(&soft_line_break_or_space(), &token("cccccccccccccccccccccccccccccc"))
|
||||
/// .entry(&soft_line_break_or_space(), &token("dddddddddddddddddddddddddddddd"))
|
||||
/// .finish()
|
||||
/// })])?;
|
||||
///
|
||||
|
@ -142,10 +142,10 @@ impl<'buf, Context> Formatter<'buf, Context> {
|
|||
///
|
||||
/// # fn main() -> FormatResult<()> {
|
||||
/// let entries = vec![
|
||||
/// text("<b>Important: </b>"),
|
||||
/// text("Please do not commit memory bugs such as segfaults, buffer overflows, etc. otherwise you "),
|
||||
/// text("<em>will</em>"),
|
||||
/// text(" be reprimanded")
|
||||
/// token("<b>Important: </b>"),
|
||||
/// token("Please do not commit memory bugs such as segfaults, buffer overflows, etc. otherwise you "),
|
||||
/// token("<em>will</em>"),
|
||||
/// token(" be reprimanded")
|
||||
/// ];
|
||||
///
|
||||
/// let formatted = format!(SimpleFormatContext::default(), [format_with(|f| {
|
||||
|
|
|
@ -455,7 +455,7 @@ pub type FormatResult<F> = Result<F, FormatError>;
|
|||
/// fn fmt(&self, f: &mut Formatter<SimpleFormatContext>) -> FormatResult<()> {
|
||||
/// write!(f, [
|
||||
/// hard_line_break(),
|
||||
/// dynamic_text(&self.0, None),
|
||||
/// text(&self.0, None),
|
||||
/// hard_line_break(),
|
||||
/// ])
|
||||
/// }
|
||||
|
@ -704,7 +704,7 @@ where
|
|||
/// let mut state = FormatState::new(SimpleFormatContext::default());
|
||||
/// let mut buffer = VecBuffer::new(&mut state);
|
||||
///
|
||||
/// write!(&mut buffer, [format_args!(text("Hello World"))])?;
|
||||
/// write!(&mut buffer, [format_args!(token("Hello World"))])?;
|
||||
///
|
||||
/// let formatted = Formatted::new(Document::from(buffer.into_vec()), SimpleFormatContext::default());
|
||||
///
|
||||
|
@ -723,7 +723,7 @@ where
|
|||
/// let mut state = FormatState::new(SimpleFormatContext::default());
|
||||
/// let mut buffer = VecBuffer::new(&mut state);
|
||||
///
|
||||
/// write!(&mut buffer, [text("Hello World")])?;
|
||||
/// write!(&mut buffer, [token("Hello World")])?;
|
||||
///
|
||||
/// let formatted = Formatted::new(Document::from(buffer.into_vec()), SimpleFormatContext::default());
|
||||
///
|
||||
|
@ -754,7 +754,7 @@ pub fn write<Context>(
|
|||
/// use ruff_formatter::{format, format_args};
|
||||
///
|
||||
/// # fn main() -> FormatResult<()> {
|
||||
/// let formatted = format!(SimpleFormatContext::default(), [&format_args!(text("test"))])?;
|
||||
/// let formatted = format!(SimpleFormatContext::default(), [&format_args!(token("test"))])?;
|
||||
/// assert_eq!("test", formatted.print()?.as_code());
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
|
@ -767,7 +767,7 @@ pub fn write<Context>(
|
|||
/// use ruff_formatter::{format};
|
||||
///
|
||||
/// # fn main() -> FormatResult<()> {
|
||||
/// let formatted = format!(SimpleFormatContext::default(), [text("test")])?;
|
||||
/// let formatted = format!(SimpleFormatContext::default(), [token("test")])?;
|
||||
/// assert_eq!("test", formatted.print()?.as_code());
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
///
|
||||
/// # fn main() -> FormatResult<()> {
|
||||
/// let formatted = format!(SimpleFormatContext::default(), [
|
||||
/// format_args!(text("Hello World"))
|
||||
/// format_args!(token("Hello World"))
|
||||
/// ])?;
|
||||
///
|
||||
/// assert_eq!("Hello World", formatted.print()?.as_code());
|
||||
|
@ -52,15 +52,15 @@ macro_rules! format_args {
|
|||
/// # fn main() -> FormatResult<()> {
|
||||
/// let mut state = FormatState::new(SimpleFormatContext::default());
|
||||
/// let mut buffer = VecBuffer::new(&mut state);
|
||||
/// write!(&mut buffer, [text("Hello"), space()])?;
|
||||
/// write!(&mut buffer, [text("World")])?;
|
||||
/// write!(&mut buffer, [token("Hello"), space()])?;
|
||||
/// write!(&mut buffer, [token("World")])?;
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// buffer.into_vec(),
|
||||
/// vec![
|
||||
/// FormatElement::StaticText { text: "Hello" },
|
||||
/// FormatElement::Token { text: "Hello" },
|
||||
/// FormatElement::Space,
|
||||
/// FormatElement::StaticText { text: "World" },
|
||||
/// FormatElement::Token { text: "World" },
|
||||
/// ]
|
||||
/// );
|
||||
/// # Ok(())
|
||||
|
@ -86,10 +86,10 @@ macro_rules! write {
|
|||
/// let mut state = FormatState::new(SimpleFormatContext::default());
|
||||
/// let mut buffer = VecBuffer::new(&mut state);
|
||||
///
|
||||
/// dbg_write!(buffer, [text("Hello")])?;
|
||||
/// dbg_write!(buffer, [token("Hello")])?;
|
||||
/// // ^-- prints: [src/main.rs:7][0] = StaticToken("Hello")
|
||||
///
|
||||
/// assert_eq!(buffer.into_vec(), vec![FormatElement::StaticText { text: "Hello" }]);
|
||||
/// assert_eq!(buffer.into_vec(), vec![FormatElement::Token { text: "Hello" }]);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
|
@ -126,14 +126,14 @@ macro_rules! dbg_write {
|
|||
/// use ruff_formatter::prelude::*;
|
||||
/// use ruff_formatter::format;
|
||||
///
|
||||
/// let formatted = format!(SimpleFormatContext::default(), [text("("), text("a"), text(")")]).unwrap();
|
||||
/// let formatted = format!(SimpleFormatContext::default(), [token("("), token("a"), token(")")]).unwrap();
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// formatted.into_document(),
|
||||
/// Document::from(vec![
|
||||
/// FormatElement::StaticText { text: "(" },
|
||||
/// FormatElement::StaticText { text: "a" },
|
||||
/// FormatElement::StaticText { text: ")" },
|
||||
/// FormatElement::Token { text: "(" },
|
||||
/// FormatElement::Token { text: "a" },
|
||||
/// FormatElement::Token { text: ")" },
|
||||
/// ])
|
||||
/// );
|
||||
/// ```
|
||||
|
@ -160,49 +160,49 @@ macro_rules! format {
|
|||
/// let formatted = format!(
|
||||
/// SimpleFormatContext::default(),
|
||||
/// [
|
||||
/// text("aVeryLongIdentifier"),
|
||||
/// token("aVeryLongIdentifier"),
|
||||
/// best_fitting!(
|
||||
/// // Everything fits on a single line
|
||||
/// format_args!(
|
||||
/// text("("),
|
||||
/// token("("),
|
||||
/// group(&format_args![
|
||||
/// text("["),
|
||||
/// token("["),
|
||||
/// soft_block_indent(&format_args![
|
||||
/// text("1,"),
|
||||
/// token("1,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("2,"),
|
||||
/// token("2,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("3"),
|
||||
/// token("3"),
|
||||
/// ]),
|
||||
/// text("]")
|
||||
/// token("]")
|
||||
/// ]),
|
||||
/// text(")")
|
||||
/// token(")")
|
||||
/// ),
|
||||
///
|
||||
/// // Breaks after `[`, but prints all elements on a single line
|
||||
/// format_args!(
|
||||
/// text("("),
|
||||
/// text("["),
|
||||
/// block_indent(&text("1, 2, 3")),
|
||||
/// text("]"),
|
||||
/// text(")"),
|
||||
/// token("("),
|
||||
/// token("["),
|
||||
/// block_indent(&token("1, 2, 3")),
|
||||
/// token("]"),
|
||||
/// token(")"),
|
||||
/// ),
|
||||
///
|
||||
/// // Breaks after `[` and prints each element on a single line
|
||||
/// format_args!(
|
||||
/// text("("),
|
||||
/// token("("),
|
||||
/// block_indent(&format_args![
|
||||
/// text("["),
|
||||
/// token("["),
|
||||
/// block_indent(&format_args![
|
||||
/// text("1,"),
|
||||
/// token("1,"),
|
||||
/// hard_line_break(),
|
||||
/// text("2,"),
|
||||
/// token("2,"),
|
||||
/// hard_line_break(),
|
||||
/// text("3"),
|
||||
/// token("3"),
|
||||
/// ]),
|
||||
/// text("]"),
|
||||
/// token("]"),
|
||||
/// ]),
|
||||
/// text(")")
|
||||
/// token(")")
|
||||
/// )
|
||||
/// )
|
||||
/// ]
|
||||
|
@ -251,38 +251,38 @@ macro_rules! format {
|
|||
/// best_fitting!(
|
||||
/// // Prints the method call on the line but breaks the array.
|
||||
/// format_args!(
|
||||
/// text("expect(a).toMatch("),
|
||||
/// token("expect(a).toMatch("),
|
||||
/// group(&format_args![
|
||||
/// text("["),
|
||||
/// token("["),
|
||||
/// soft_block_indent(&format_args![
|
||||
/// text("1,"),
|
||||
/// token("1,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("2,"),
|
||||
/// token("2,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("3"),
|
||||
/// token("3"),
|
||||
/// ]),
|
||||
/// text("]")
|
||||
/// token("]")
|
||||
/// ]).should_expand(true),
|
||||
/// text(")")
|
||||
/// token(")")
|
||||
/// ),
|
||||
///
|
||||
/// // Breaks after `(`
|
||||
/// format_args!(
|
||||
/// text("expect(a).toMatch("),
|
||||
/// token("expect(a).toMatch("),
|
||||
/// group(&soft_block_indent(
|
||||
/// &group(&format_args![
|
||||
/// text("["),
|
||||
/// token("["),
|
||||
/// soft_block_indent(&format_args![
|
||||
/// text("1,"),
|
||||
/// token("1,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("2,"),
|
||||
/// token("2,"),
|
||||
/// soft_line_break_or_space(),
|
||||
/// text("3"),
|
||||
/// token("3"),
|
||||
/// ]),
|
||||
/// text("]")
|
||||
/// token("]")
|
||||
/// ]).should_expand(true),
|
||||
/// )).should_expand(true),
|
||||
/// text(")")
|
||||
/// token(")")
|
||||
/// ),
|
||||
/// )
|
||||
/// ]
|
||||
|
@ -345,7 +345,7 @@ mod tests {
|
|||
|
||||
impl Format<()> for TestFormat {
|
||||
fn fmt(&self, f: &mut Formatter<()>) -> FormatResult<()> {
|
||||
write!(f, [text("test")])
|
||||
write!(f, [token("test")])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,7 +358,7 @@ mod tests {
|
|||
|
||||
assert_eq!(
|
||||
buffer.into_vec(),
|
||||
vec![FormatElement::StaticText { text: "test" }]
|
||||
vec![FormatElement::Token { text: "test" }]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -369,18 +369,18 @@ mod tests {
|
|||
|
||||
write![
|
||||
&mut buffer,
|
||||
[text("a"), space(), text("simple"), space(), TestFormat]
|
||||
[token("a"), space(), token("simple"), space(), TestFormat]
|
||||
]
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
buffer.into_vec(),
|
||||
vec![
|
||||
FormatElement::StaticText { text: "a" },
|
||||
FormatElement::Token { text: "a" },
|
||||
FormatElement::Space,
|
||||
FormatElement::StaticText { text: "simple" },
|
||||
FormatElement::Token { text: "simple" },
|
||||
FormatElement::Space,
|
||||
FormatElement::StaticText { text: "test" }
|
||||
FormatElement::Token { text: "test" }
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@ -394,41 +394,41 @@ mod tests {
|
|||
let formatted_best_fitting = format!(
|
||||
SimpleFormatContext::default(),
|
||||
[
|
||||
text("aVeryLongIdentifier"),
|
||||
token("aVeryLongIdentifier"),
|
||||
soft_line_break_or_space(),
|
||||
best_fitting![
|
||||
format_args![text(
|
||||
format_args![token(
|
||||
"Something that will not fit on a line with 30 character print width."
|
||||
)],
|
||||
format_args![group(&format_args![
|
||||
text("Start"),
|
||||
token("Start"),
|
||||
soft_line_break(),
|
||||
group(&soft_block_indent(&format_args![
|
||||
text("1,"),
|
||||
token("1,"),
|
||||
soft_line_break_or_space(),
|
||||
text("2,"),
|
||||
token("2,"),
|
||||
soft_line_break_or_space(),
|
||||
text("3"),
|
||||
token("3"),
|
||||
])),
|
||||
soft_line_break_or_space(),
|
||||
soft_block_indent(&format_args![
|
||||
text("1,"),
|
||||
token("1,"),
|
||||
soft_line_break_or_space(),
|
||||
text("2,"),
|
||||
token("2,"),
|
||||
soft_line_break_or_space(),
|
||||
group(&format_args!(
|
||||
text("A,"),
|
||||
token("A,"),
|
||||
soft_line_break_or_space(),
|
||||
text("B")
|
||||
token("B")
|
||||
)),
|
||||
soft_line_break_or_space(),
|
||||
text("3")
|
||||
token("3")
|
||||
]),
|
||||
soft_line_break_or_space(),
|
||||
text("End")
|
||||
token("End")
|
||||
])
|
||||
.should_expand(true)],
|
||||
format_args!(text("Most"), hard_line_break(), text("Expanded"))
|
||||
format_args!(token("Most"), hard_line_break(), token("Expanded"))
|
||||
]
|
||||
]
|
||||
)
|
||||
|
@ -439,34 +439,34 @@ mod tests {
|
|||
let formatted_normal_list = format!(
|
||||
SimpleFormatContext::default(),
|
||||
[
|
||||
text("aVeryLongIdentifier"),
|
||||
token("aVeryLongIdentifier"),
|
||||
soft_line_break_or_space(),
|
||||
format_args![
|
||||
text("Start"),
|
||||
token("Start"),
|
||||
soft_line_break(),
|
||||
&group(&soft_block_indent(&format_args![
|
||||
text("1,"),
|
||||
token("1,"),
|
||||
soft_line_break_or_space(),
|
||||
text("2,"),
|
||||
token("2,"),
|
||||
soft_line_break_or_space(),
|
||||
text("3"),
|
||||
token("3"),
|
||||
])),
|
||||
soft_line_break_or_space(),
|
||||
&soft_block_indent(&format_args![
|
||||
text("1,"),
|
||||
token("1,"),
|
||||
soft_line_break_or_space(),
|
||||
text("2,"),
|
||||
token("2,"),
|
||||
soft_line_break_or_space(),
|
||||
group(&format_args!(
|
||||
text("A,"),
|
||||
token("A,"),
|
||||
soft_line_break_or_space(),
|
||||
text("B")
|
||||
token("B")
|
||||
)),
|
||||
soft_line_break_or_space(),
|
||||
text("3")
|
||||
token("3")
|
||||
]),
|
||||
soft_line_break_or_space(),
|
||||
text("End")
|
||||
token("End")
|
||||
],
|
||||
]
|
||||
)
|
||||
|
|
|
@ -95,31 +95,31 @@ impl<'a> Printer<'a> {
|
|||
let args = stack.top();
|
||||
|
||||
match element {
|
||||
FormatElement::Space => self.print_text(" ", None),
|
||||
FormatElement::StaticText { text } => self.print_text(text, None),
|
||||
FormatElement::DynamicText { text } => self.print_text(text, None),
|
||||
FormatElement::Space => self.print_text(Text::Token(" "), None),
|
||||
FormatElement::Token { text } => self.print_text(Text::Token(text), None),
|
||||
FormatElement::Text { text } => self.print_text(Text::Text(text), None),
|
||||
FormatElement::SourceCodeSlice { slice, .. } => {
|
||||
let text = slice.text(self.source_code);
|
||||
self.print_text(text, Some(slice.range()));
|
||||
self.print_text(Text::Text(text), Some(slice.range()));
|
||||
}
|
||||
FormatElement::Line(line_mode) => {
|
||||
if args.mode().is_flat()
|
||||
&& matches!(line_mode, LineMode::Soft | LineMode::SoftOrSpace)
|
||||
{
|
||||
if line_mode == &LineMode::SoftOrSpace {
|
||||
self.print_text(" ", None);
|
||||
self.print_text(Text::Token(" "), None);
|
||||
}
|
||||
} else if self.state.line_suffixes.has_pending() {
|
||||
self.flush_line_suffixes(queue, stack, Some(element));
|
||||
} else {
|
||||
// Only print a newline if the current line isn't already empty
|
||||
if self.state.line_width > 0 {
|
||||
self.print_str("\n");
|
||||
self.print_char('\n');
|
||||
}
|
||||
|
||||
// Print a second line break if this is an empty line
|
||||
if line_mode == &LineMode::Empty {
|
||||
self.print_str("\n");
|
||||
self.print_char('\n');
|
||||
}
|
||||
|
||||
self.state.pending_indent = args.indention();
|
||||
|
@ -352,7 +352,7 @@ impl<'a> Printer<'a> {
|
|||
Ok(print_mode)
|
||||
}
|
||||
|
||||
fn print_text(&mut self, text: &str, source_range: Option<TextRange>) {
|
||||
fn print_text(&mut self, text: Text, source_range: Option<TextRange>) {
|
||||
if !self.state.pending_indent.is_empty() {
|
||||
let (indent_char, repeat_count) = match self.options.indent_style() {
|
||||
IndentStyle::Tab => ('\t', 1),
|
||||
|
@ -390,7 +390,18 @@ impl<'a> Printer<'a> {
|
|||
|
||||
self.push_marker();
|
||||
|
||||
self.print_str(text);
|
||||
match text {
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
Text::Token(token) => {
|
||||
self.state.buffer.push_str(token);
|
||||
self.state.line_width += token.len() as u32;
|
||||
}
|
||||
Text::Text(text) => {
|
||||
for char in text.chars() {
|
||||
self.print_char(char);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(range) = source_range {
|
||||
self.state.source_position = range.end();
|
||||
|
@ -718,12 +729,6 @@ impl<'a> Printer<'a> {
|
|||
invalid_end_tag(TagKind::Entry, stack.top_kind())
|
||||
}
|
||||
|
||||
fn print_str(&mut self, content: &str) {
|
||||
for char in content.chars() {
|
||||
self.print_char(char);
|
||||
}
|
||||
}
|
||||
|
||||
fn print_char(&mut self, char: char) {
|
||||
if char == '\n' {
|
||||
self.state
|
||||
|
@ -1047,12 +1052,12 @@ impl<'a, 'print> FitsMeasurer<'a, 'print> {
|
|||
let args = self.stack.top();
|
||||
|
||||
match element {
|
||||
FormatElement::Space => return Ok(self.fits_text(" ", args)),
|
||||
FormatElement::Space => return Ok(self.fits_text(Text::Token(" "), args)),
|
||||
|
||||
FormatElement::Line(line_mode) => {
|
||||
match args.mode() {
|
||||
PrintMode::Flat => match line_mode {
|
||||
LineMode::SoftOrSpace => return Ok(self.fits_text(" ", args)),
|
||||
LineMode::SoftOrSpace => return Ok(self.fits_text(Text::Token(" "), args)),
|
||||
LineMode::Soft => {}
|
||||
LineMode::Hard | LineMode::Empty => {
|
||||
return Ok(if self.must_be_flat {
|
||||
|
@ -1081,11 +1086,11 @@ impl<'a, 'print> FitsMeasurer<'a, 'print> {
|
|||
}
|
||||
}
|
||||
|
||||
FormatElement::StaticText { text } => return Ok(self.fits_text(text, args)),
|
||||
FormatElement::DynamicText { text, .. } => return Ok(self.fits_text(text, args)),
|
||||
FormatElement::Token { text } => return Ok(self.fits_text(Text::Token(text), args)),
|
||||
FormatElement::Text { text, .. } => return Ok(self.fits_text(Text::Text(text), args)),
|
||||
FormatElement::SourceCodeSlice { slice, .. } => {
|
||||
let text = slice.text(self.printer.source_code);
|
||||
return Ok(self.fits_text(text, args));
|
||||
return Ok(self.fits_text(Text::Text(text), args));
|
||||
}
|
||||
FormatElement::LineSuffixBoundary => {
|
||||
if self.state.has_line_suffix {
|
||||
|
@ -1293,31 +1298,39 @@ impl<'a, 'print> FitsMeasurer<'a, 'print> {
|
|||
Fits::Maybe
|
||||
}
|
||||
|
||||
fn fits_text(&mut self, text: &str, args: PrintElementArgs) -> Fits {
|
||||
fn fits_text(&mut self, text: Text, args: PrintElementArgs) -> Fits {
|
||||
let indent = std::mem::take(&mut self.state.pending_indent);
|
||||
self.state.line_width +=
|
||||
u32::from(indent.level()) * self.options().indent_width() + u32::from(indent.align());
|
||||
|
||||
for c in text.chars() {
|
||||
let char_width = match c {
|
||||
'\t' => self.options().tab_width.value(),
|
||||
'\n' => {
|
||||
if self.must_be_flat {
|
||||
return Fits::No;
|
||||
}
|
||||
match args.measure_mode() {
|
||||
MeasureMode::FirstLine => return Fits::Yes,
|
||||
MeasureMode::AllLines => {
|
||||
self.state.line_width = 0;
|
||||
continue;
|
||||
match text {
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
Text::Token(token) => {
|
||||
self.state.line_width += token.len() as u32;
|
||||
}
|
||||
Text::Text(text) => {
|
||||
for c in text.chars() {
|
||||
let char_width = match c {
|
||||
'\t' => self.options().tab_width.value(),
|
||||
'\n' => {
|
||||
if self.must_be_flat {
|
||||
return Fits::No;
|
||||
}
|
||||
match args.measure_mode() {
|
||||
MeasureMode::FirstLine => return Fits::Yes,
|
||||
MeasureMode::AllLines => {
|
||||
self.state.line_width = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// SAFETY: A u32 is sufficient to format files <= 4GB
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
c => c.width().unwrap_or(0) as u32,
|
||||
};
|
||||
self.state.line_width += char_width;
|
||||
}
|
||||
// SAFETY: A u32 is sufficient to format files <= 4GB
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
c => c.width().unwrap_or(0) as u32,
|
||||
};
|
||||
self.state.line_width += char_width;
|
||||
}
|
||||
}
|
||||
|
||||
if self.state.line_width > self.options().line_width.into() {
|
||||
|
@ -1434,6 +1447,14 @@ impl From<BestFittingMode> for MeasureMode {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
enum Text<'a> {
|
||||
/// ASCII only text that contains no line breaks or tab characters.
|
||||
Token(&'a str),
|
||||
/// Arbitrary text. May contain `\n` line breaks, tab characters, or unicode characters.
|
||||
Text(&'a str),
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::prelude::*;
|
||||
|
@ -1469,10 +1490,10 @@ mod tests {
|
|||
fn it_prints_a_group_on_a_single_line_if_it_fits() {
|
||||
let result = format(&FormatArrayElements {
|
||||
items: vec![
|
||||
&text("\"a\""),
|
||||
&text("\"b\""),
|
||||
&text("\"c\""),
|
||||
&text("\"d\""),
|
||||
&token("\"a\""),
|
||||
&token("\"b\""),
|
||||
&token("\"c\""),
|
||||
&token("\"d\""),
|
||||
],
|
||||
});
|
||||
|
||||
|
@ -1482,17 +1503,17 @@ mod tests {
|
|||
#[test]
|
||||
fn it_tracks_the_indent_for_each_token() {
|
||||
let formatted = format(&format_args!(
|
||||
text("a"),
|
||||
token("a"),
|
||||
soft_block_indent(&format_args!(
|
||||
text("b"),
|
||||
token("b"),
|
||||
soft_block_indent(&format_args!(
|
||||
text("c"),
|
||||
soft_block_indent(&format_args!(text("d"), soft_line_break(), text("d"),)),
|
||||
text("c"),
|
||||
token("c"),
|
||||
soft_block_indent(&format_args!(token("d"), soft_line_break(), token("d"),)),
|
||||
token("c"),
|
||||
)),
|
||||
text("b"),
|
||||
token("b"),
|
||||
)),
|
||||
text("a")
|
||||
token("a")
|
||||
));
|
||||
|
||||
assert_eq!(
|
||||
|
@ -1517,9 +1538,9 @@ a"#,
|
|||
|
||||
let result = format_with_options(
|
||||
&format_args![
|
||||
text("function main() {"),
|
||||
block_indent(&text("let x = `This is a multiline\nstring`;")),
|
||||
text("}"),
|
||||
token("function main() {"),
|
||||
block_indent(&text("let x = `This is a multiline\nstring`;", None)),
|
||||
token("}"),
|
||||
hard_line_break()
|
||||
],
|
||||
options,
|
||||
|
@ -1535,8 +1556,8 @@ a"#,
|
|||
fn it_breaks_a_group_if_a_string_contains_a_newline() {
|
||||
let result = format(&FormatArrayElements {
|
||||
items: vec![
|
||||
&text("`This is a string spanning\ntwo lines`"),
|
||||
&text("\"b\""),
|
||||
&text("`This is a string spanning\ntwo lines`", None),
|
||||
&token("\"b\""),
|
||||
],
|
||||
});
|
||||
|
||||
|
@ -1551,7 +1572,7 @@ two lines`,
|
|||
}
|
||||
#[test]
|
||||
fn it_breaks_a_group_if_it_contains_a_hard_line_break() {
|
||||
let result = format(&group(&format_args![text("a"), block_indent(&text("b"))]));
|
||||
let result = format(&group(&format_args![token("a"), block_indent(&token("b"))]));
|
||||
|
||||
assert_eq!("a\n b\n", result.as_code());
|
||||
}
|
||||
|
@ -1560,17 +1581,17 @@ two lines`,
|
|||
fn it_breaks_parent_groups_if_they_dont_fit_on_a_single_line() {
|
||||
let result = format(&FormatArrayElements {
|
||||
items: vec![
|
||||
&text("\"a\""),
|
||||
&text("\"b\""),
|
||||
&text("\"c\""),
|
||||
&text("\"d\""),
|
||||
&token("\"a\""),
|
||||
&token("\"b\""),
|
||||
&token("\"c\""),
|
||||
&token("\"d\""),
|
||||
&FormatArrayElements {
|
||||
items: vec![
|
||||
&text("\"0123456789\""),
|
||||
&text("\"0123456789\""),
|
||||
&text("\"0123456789\""),
|
||||
&text("\"0123456789\""),
|
||||
&text("\"0123456789\""),
|
||||
&token("\"0123456789\""),
|
||||
&token("\"0123456789\""),
|
||||
&token("\"0123456789\""),
|
||||
&token("\"0123456789\""),
|
||||
&token("\"0123456789\""),
|
||||
],
|
||||
},
|
||||
],
|
||||
|
@ -1599,7 +1620,7 @@ two lines`,
|
|||
|
||||
let result = format_with_options(
|
||||
&FormatArrayElements {
|
||||
items: vec![&text("'a'"), &text("'b'"), &text("'c'"), &text("'d'")],
|
||||
items: vec![&token("'a'"), &token("'b'"), &token("'c'"), &token("'d'")],
|
||||
},
|
||||
options,
|
||||
);
|
||||
|
@ -1610,11 +1631,11 @@ two lines`,
|
|||
#[test]
|
||||
fn it_prints_consecutive_hard_lines_as_one() {
|
||||
let result = format(&format_args![
|
||||
text("a"),
|
||||
token("a"),
|
||||
hard_line_break(),
|
||||
hard_line_break(),
|
||||
hard_line_break(),
|
||||
text("b"),
|
||||
token("b"),
|
||||
]);
|
||||
|
||||
assert_eq!("a\nb", result.as_code());
|
||||
|
@ -1623,11 +1644,11 @@ two lines`,
|
|||
#[test]
|
||||
fn it_prints_consecutive_empty_lines_as_many() {
|
||||
let result = format(&format_args![
|
||||
text("a"),
|
||||
token("a"),
|
||||
empty_line(),
|
||||
empty_line(),
|
||||
empty_line(),
|
||||
text("b"),
|
||||
token("b"),
|
||||
]);
|
||||
|
||||
assert_eq!("a\n\n\n\nb", result.as_code());
|
||||
|
@ -1636,12 +1657,12 @@ two lines`,
|
|||
#[test]
|
||||
fn it_prints_consecutive_mixed_lines_as_many() {
|
||||
let result = format(&format_args![
|
||||
text("a"),
|
||||
token("a"),
|
||||
empty_line(),
|
||||
hard_line_break(),
|
||||
empty_line(),
|
||||
hard_line_break(),
|
||||
text("b"),
|
||||
token("b"),
|
||||
]);
|
||||
|
||||
assert_eq!("a\n\n\nb", result.as_code());
|
||||
|
@ -1658,37 +1679,37 @@ two lines`,
|
|||
// These all fit on the same line together
|
||||
.entry(
|
||||
&soft_line_break_or_space(),
|
||||
&format_args!(text("1"), text(",")),
|
||||
&format_args!(token("1"), token(",")),
|
||||
)
|
||||
.entry(
|
||||
&soft_line_break_or_space(),
|
||||
&format_args!(text("2"), text(",")),
|
||||
&format_args!(token("2"), token(",")),
|
||||
)
|
||||
.entry(
|
||||
&soft_line_break_or_space(),
|
||||
&format_args!(text("3"), text(",")),
|
||||
&format_args!(token("3"), token(",")),
|
||||
)
|
||||
// This one fits on a line by itself,
|
||||
.entry(
|
||||
&soft_line_break_or_space(),
|
||||
&format_args!(text("723493294"), text(",")),
|
||||
&format_args!(token("723493294"), token(",")),
|
||||
)
|
||||
// fits without breaking
|
||||
.entry(
|
||||
&soft_line_break_or_space(),
|
||||
&group(&format_args!(
|
||||
text("["),
|
||||
soft_block_indent(&text("5")),
|
||||
text("],")
|
||||
token("["),
|
||||
soft_block_indent(&token("5")),
|
||||
token("],")
|
||||
)),
|
||||
)
|
||||
// this one must be printed in expanded mode to fit
|
||||
.entry(
|
||||
&soft_line_break_or_space(),
|
||||
&group(&format_args!(
|
||||
text("["),
|
||||
soft_block_indent(&text("123456789")),
|
||||
text("]"),
|
||||
token("["),
|
||||
soft_block_indent(&token("123456789")),
|
||||
token("]"),
|
||||
)),
|
||||
)
|
||||
.finish()
|
||||
|
@ -1713,27 +1734,27 @@ two lines`,
|
|||
fn line_suffix_printed_at_end() {
|
||||
let printed = format(&format_args![
|
||||
group(&format_args![
|
||||
text("["),
|
||||
token("["),
|
||||
soft_block_indent(&format_with(|f| {
|
||||
f.fill()
|
||||
.entry(
|
||||
&soft_line_break_or_space(),
|
||||
&format_args!(text("1"), text(",")),
|
||||
&format_args!(token("1"), token(",")),
|
||||
)
|
||||
.entry(
|
||||
&soft_line_break_or_space(),
|
||||
&format_args!(text("2"), text(",")),
|
||||
&format_args!(token("2"), token(",")),
|
||||
)
|
||||
.entry(
|
||||
&soft_line_break_or_space(),
|
||||
&format_args!(text("3"), if_group_breaks(&text(","))),
|
||||
&format_args!(token("3"), if_group_breaks(&token(","))),
|
||||
)
|
||||
.finish()
|
||||
})),
|
||||
text("]")
|
||||
token("]")
|
||||
]),
|
||||
text(";"),
|
||||
line_suffix(&format_args![space(), text("// trailing")], 0)
|
||||
token(";"),
|
||||
line_suffix(&format_args![space(), token("// trailing")], 0)
|
||||
]);
|
||||
|
||||
assert_eq!(printed.as_code(), "[1, 2, 3]; // trailing");
|
||||
|
@ -1743,27 +1764,27 @@ two lines`,
|
|||
fn line_suffix_with_reserved_width() {
|
||||
let printed = format(&format_args![
|
||||
group(&format_args![
|
||||
text("["),
|
||||
token("["),
|
||||
soft_block_indent(&format_with(|f| {
|
||||
f.fill()
|
||||
.entry(
|
||||
&soft_line_break_or_space(),
|
||||
&format_args!(text("1"), text(",")),
|
||||
&format_args!(token("1"), token(",")),
|
||||
)
|
||||
.entry(
|
||||
&soft_line_break_or_space(),
|
||||
&format_args!(text("2"), text(",")),
|
||||
&format_args!(token("2"), token(",")),
|
||||
)
|
||||
.entry(
|
||||
&soft_line_break_or_space(),
|
||||
&format_args!(text("3"), if_group_breaks(&text(","))),
|
||||
&format_args!(token("3"), if_group_breaks(&token(","))),
|
||||
)
|
||||
.finish()
|
||||
})),
|
||||
text("]")
|
||||
token("]")
|
||||
]),
|
||||
text(";"),
|
||||
line_suffix(&format_args![space(), text("// Using reserved width causes this content to not fit even though it's a line suffix element")], 93)
|
||||
token(";"),
|
||||
line_suffix(&format_args![space(), token("// Using reserved width causes this content to not fit even though it's a line suffix element")], 93)
|
||||
]);
|
||||
|
||||
assert_eq!(printed.as_code(), "[\n 1, 2, 3\n]; // Using reserved width causes this content to not fit even though it's a line suffix element");
|
||||
|
@ -1777,15 +1798,15 @@ two lines`,
|
|||
f,
|
||||
[
|
||||
group(&format_args![
|
||||
text("The referenced group breaks."),
|
||||
token("The referenced group breaks."),
|
||||
hard_line_break()
|
||||
])
|
||||
.with_group_id(Some(group_id)),
|
||||
group(&format_args![
|
||||
text("This group breaks because:"),
|
||||
token("This group breaks because:"),
|
||||
soft_line_break_or_space(),
|
||||
if_group_fits_on_line(&text("This content fits but should not be printed.")).with_group_id(Some(group_id)),
|
||||
if_group_breaks(&text("It measures with the 'if_group_breaks' variant because the referenced group breaks and that's just way too much text.")).with_group_id(Some(group_id)),
|
||||
if_group_fits_on_line(&token("This content fits but should not be printed.")).with_group_id(Some(group_id)),
|
||||
if_group_breaks(&token("It measures with the 'if_group_breaks' variant because the referenced group breaks and that's just way too much text.")).with_group_id(Some(group_id)),
|
||||
])
|
||||
]
|
||||
)
|
||||
|
@ -1805,7 +1826,7 @@ two lines`,
|
|||
write!(
|
||||
f,
|
||||
[
|
||||
group(&text("Group with id-2")).with_group_id(Some(id_2)),
|
||||
group(&token("Group with id-2")).with_group_id(Some(id_2)),
|
||||
hard_line_break()
|
||||
]
|
||||
)?;
|
||||
|
@ -1813,7 +1834,7 @@ two lines`,
|
|||
write!(
|
||||
f,
|
||||
[
|
||||
group(&text("Group with id-1 does not fit on the line because it exceeds the line width of 80 characters by")).with_group_id(Some(id_1)),
|
||||
group(&token("Group with id-1 does not fit on the line because it exceeds the line width of 80 characters by")).with_group_id(Some(id_1)),
|
||||
hard_line_break()
|
||||
]
|
||||
)?;
|
||||
|
@ -1821,9 +1842,9 @@ two lines`,
|
|||
write!(
|
||||
f,
|
||||
[
|
||||
if_group_fits_on_line(&text("Group 2 fits")).with_group_id(Some(id_2)),
|
||||
if_group_fits_on_line(&token("Group 2 fits")).with_group_id(Some(id_2)),
|
||||
hard_line_break(),
|
||||
if_group_breaks(&text("Group 1 breaks")).with_group_id(Some(id_1))
|
||||
if_group_breaks(&token("Group 1 breaks")).with_group_id(Some(id_1))
|
||||
]
|
||||
)
|
||||
});
|
||||
|
@ -1848,15 +1869,15 @@ Group 1 breaks"#
|
|||
write!(
|
||||
f,
|
||||
[group(&format_args!(
|
||||
text("["),
|
||||
token("["),
|
||||
soft_block_indent(&format_args!(
|
||||
format_with(|f| f
|
||||
.join_with(format_args!(text(","), soft_line_break_or_space()))
|
||||
.join_with(format_args!(token(","), soft_line_break_or_space()))
|
||||
.entries(&self.items)
|
||||
.finish()),
|
||||
if_group_breaks(&text(",")),
|
||||
if_group_breaks(&token(",")),
|
||||
)),
|
||||
text("]")
|
||||
token("]")
|
||||
))]
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue