pub enum Doc<'a> {
// some variants omitted
}Expand description
The data structure that describes about pretty printing.
You should avoid using variants on this enum; instead, use helper functions on this enum.
Implementations§
Source§impl<'a> Doc<'a>
impl<'a> Doc<'a>
Sourcepub fn text(s: impl Into<Cow<'a, str>>) -> Doc<'a>
pub fn text(s: impl Into<Cow<'a, str>>) -> Doc<'a>
Insert a piece of text. It must not contain line breaks.
use tiny_pretty::{print, Doc};
let doc = Doc::text("code");
assert_eq!("code", &print(&doc, &Default::default()));
let doc = Doc::text(String::from("code"));
assert_eq!("code", &print(&doc, &Default::default()));Sourcepub fn nil() -> Doc<'a>
pub fn nil() -> Doc<'a>
Empty doc, which does nothing.
use tiny_pretty::{print, Doc};
let doc = Doc::nil();
assert!(print(&doc, &Default::default()).is_empty());Sourcepub fn space() -> Doc<'a>
pub fn space() -> Doc<'a>
Just a space. This is just short for calling text with a space.
use tiny_pretty::{print, Doc};
let doc = Doc::space();
assert_eq!(" ", &print(&doc, &Default::default()));Sourcepub fn hard_line() -> Doc<'a>
pub fn hard_line() -> Doc<'a>
Force to print a line break.
use tiny_pretty::{print, Doc, LineBreak, PrintOptions};
let doc = Doc::hard_line();
assert_eq!("\n", &print(&doc, &Default::default()));
assert_eq!("\r\n", &print(&doc, &PrintOptions {
line_break: LineBreak::Crlf,
..Default::default()
}));
// There's a `hard_line` call inside a group,
// so the group always breaks even it doesn't exceed the width limitation.
let doc = Doc::text("fn(")
.append(Doc::line_or_space())
.append(Doc::hard_line())
.group();
assert_eq!("fn(\n\n", &print(&doc, &Default::default()));Sourcepub fn soft_line() -> Doc<'a>
pub fn soft_line() -> Doc<'a>
“Soft line” allows you to put docs on a single line as many as possible. Once it’s going to exceed the width limitation, it will insert a line break, but before that it will insert spaces instead of line break.
This is different from line_or_space. See the examples below.
use tiny_pretty::{print, Doc, PrintOptions};
let options = PrintOptions { width: 10, ..Default::default() };
assert_eq!(
"aaaa bbbb\ncccc",
&print(
&Doc::list(vec![
Doc::text("aaaa"),
Doc::soft_line(),
Doc::text("bbbb"),
Doc::soft_line(),
Doc::text("cccc"),
]).group(),
&options,
),
);
assert_eq!(
"aaaa\nbbbb\ncccc",
&print(
&Doc::list(vec![
Doc::text("aaaa"),
Doc::line_or_space(),
Doc::text("bbbb"),
Doc::line_or_space(),
Doc::text("cccc"),
]).group(),
&options,
),
);Sourcepub fn empty_line() -> Doc<'a>
pub fn empty_line() -> Doc<'a>
“Empty line” is simliar to hard_line but it won’t be
affected by indentation. That is, it always prints an empty line without
spaces or tabs indented.
use tiny_pretty::{print, Doc, PrintOptions};
assert_eq!(
"\n",
&print(
&Doc::empty_line().nest(1),
&Default::default(),
),
);
assert_eq!(
"\n ",
&print(
&Doc::hard_line().nest(1),
&Default::default(),
),
);Sourcepub fn list(docs: Vec<Doc<'a>>) -> Doc<'a>
pub fn list(docs: Vec<Doc<'a>>) -> Doc<'a>
Create a list of docs.
use tiny_pretty::{print, Doc};
let doc = Doc::list(vec![Doc::text("a"), Doc::text("b"), Doc::text("c")]);
assert_eq!("abc", &print(&doc, &Default::default()));Sourcepub fn line_or_space() -> Doc<'a>
pub fn line_or_space() -> Doc<'a>
Print a space if doc can be put on a single line, otherwise print a line break.
This won’t take any effects if used outside a group: it will just print a line break.
use tiny_pretty::{print, Doc, PrintOptions};
let options = PrintOptions { width: 10, ..Default::default() };
assert_eq!(
"aaaa\nbbbb\ncccc",
&print(
&Doc::list(vec![
Doc::text("aaaa"),
Doc::line_or_space(),
Doc::text("bbbb"),
Doc::line_or_space(),
Doc::text("cccc"),
]).group(),
&options,
),
);
assert_eq!(
"a b",
&print(
&Doc::list(vec![
Doc::text("a"),
Doc::line_or_space(),
Doc::text("b"),
]).group(),
&options,
),
);
assert_eq!(
"a\nb",
&print(
&Doc::list(vec![
Doc::text("a"),
Doc::line_or_space(),
Doc::text("b"),
]), // <-- no grouping here
&options,
),
);Sourcepub fn line_or_nil() -> Doc<'a>
pub fn line_or_nil() -> Doc<'a>
Print nothing if doc can be put on a single line, otherwise print a line break.
This won’t take any effects if used outside a group: it will just print a line break.
use tiny_pretty::{print, Doc, PrintOptions};
let options = PrintOptions { width: 5, ..Default::default() };
assert_eq!(
"func(\narg",
&print(
&Doc::list(vec![
Doc::text("func("),
Doc::line_or_nil(),
Doc::text("arg"),
]).group(),
&options,
),
);
assert_eq!(
"f(arg",
&print(
&Doc::list(vec![
Doc::text("f("),
Doc::line_or_nil(),
Doc::text("arg"),
]).group(),
&options,
),
);
assert_eq!(
"f(\narg",
&print(
&Doc::list(vec![
Doc::text("f("),
Doc::line_or_nil(),
Doc::text("arg"),
]), // <-- no grouping here
&options,
),
);Sourcepub fn flat_or_break(doc_flat: Doc<'a>, doc_break: Doc<'a>) -> Doc<'a>
pub fn flat_or_break(doc_flat: Doc<'a>, doc_break: Doc<'a>) -> Doc<'a>
Apply doc_flat when it can be put on a single line,
otherwise apply doc_break.
This won’t take any effects if used outside a group: it will just apply doc_break.
use tiny_pretty::{print, Doc, PrintOptions};
let doc = Doc::list(vec![
Doc::text("function("),
Doc::line_or_nil(),
Doc::text("arg"),
Doc::flat_or_break(Doc::nil(), Doc::text(",")),
Doc::line_or_nil(),
Doc::text(")"),
]).group();
assert_eq!("function(\narg,\n)", &print(&doc, &PrintOptions {
width: 10,
..Default::default()
}));
assert_eq!("function(arg)", &print(&doc, &PrintOptions {
width: 20,
..Default::default()
}));
let doc = Doc::list(vec![
Doc::text("function("),
Doc::line_or_nil(),
Doc::text("arg"),
Doc::flat_or_break(Doc::nil(), Doc::text(",")),
Doc::line_or_nil(),
Doc::text(")"),
]); // <-- no grouping here
assert_eq!("function(\narg,\n)", &print(&doc, &PrintOptions {
width: 20,
..Default::default()
}));Sourcepub fn union(self, alternate: Doc<'a>) -> Doc<'a>
pub fn union(self, alternate: Doc<'a>) -> Doc<'a>
Try applying the current doc. If it exceeds the width limitation, apply the alternate doc.
This looks similar to flat_or_break,
but you should use flat_or_break with group as possible.
Only consider using this if there’re some hard_line calls in your doc,
since hard_line will always break in a group.
use tiny_pretty::{print, Doc, PrintOptions};
let closure = Doc::list(vec![
Doc::text("|| {"),
Doc::hard_line()
.append(
Doc::text("call2(|| {")
.append(Doc::hard_line().append(Doc::text("value")).nest(4))
.append(Doc::hard_line())
.append(Doc::text("})"))
)
.nest(4),
Doc::hard_line(),
Doc::text("}"),
]);
let doc = Doc::text("fn main() {")
.append(
Doc::hard_line()
.append(
Doc::list(vec![
Doc::text("call1("),
Doc::nil()
.append(Doc::text("very_long_arg"))
.append(Doc::text(","))
.append(Doc::space())
.append(closure.clone())
.nest(0),
Doc::text(")"),
]).union(Doc::list(vec![
Doc::text("call1("),
Doc::hard_line()
.append(Doc::text("very_long_arg"))
.append(Doc::text(","))
.append(Doc::hard_line())
.append(closure)
.nest(4),
Doc::hard_line(),
Doc::text(")"),
])),
)
.nest(4)
)
.append(Doc::hard_line())
.append(Doc::text("}"));
assert_eq!("fn main() {
call1(
very_long_arg,
|| {
call2(|| {
value
})
}
)
}", &print(&doc, &PrintOptions {
width: 10,
..Default::default()
}));
assert_eq!("fn main() {
call1(very_long_arg, || {
call2(|| {
value
})
})
}", &print(&doc, &PrintOptions {
width: 30,
..Default::default()
}));Sourcepub fn group(self) -> Doc<'a>
pub fn group(self) -> Doc<'a>
Mark the docs as a group.
For a group of docs, when printing,
they will be checked if those docs can be put on a single line.
If they can’t, it may insert line breaks according to the
line_or_space, line_or_nil
or soft_line calls in the group.
(Also, please read examples of those functions for usage of group.)
Calling this on text won’t take any effects.
use tiny_pretty::{print, Doc};
let doc = Doc::text("code").group();
assert_eq!("code", &print(&doc, &Default::default()));Sourcepub fn append(self, other: Doc<'a>) -> Doc<'a>
pub fn append(self, other: Doc<'a>) -> Doc<'a>
Join two docs.
use tiny_pretty::{print, Doc};
let doc = Doc::text("a").append(Doc::text("b")).append(Doc::text("c"));
assert_eq!("abc", &print(&doc, &Default::default()));Sourcepub fn concat(self, iter: impl Iterator<Item = Doc<'a>>) -> Doc<'a>
pub fn concat(self, iter: impl Iterator<Item = Doc<'a>>) -> Doc<'a>
Concatenate an iterator whose items are docs.
use tiny_pretty::{print, Doc};
let doc = Doc::text("a").concat(vec![Doc::text("b"), Doc::text("c")].into_iter());
assert_eq!("abc", &print(&doc, &Default::default()));Sourcepub fn nest(self, size: usize) -> Doc<'a>
pub fn nest(self, size: usize) -> Doc<'a>
Increase indentation level. Usually this method should be called on group or line break. Calling this on text won’t take any effects.
use tiny_pretty::{print, Doc};
let doc = Doc::hard_line().nest(2);
assert_eq!("\n ", &print(&doc, &Default::default()));
let doc = Doc::text("code").nest(2);
assert_eq!("code", &print(&doc, &Default::default()));