Enum Doc

Source
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>

Source

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()));
Source

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());
Source

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()));
Source

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()));
Source

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,
    ),
);
Source

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(),
    ),
);
Source

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()));
Source

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,
    ),
);
Source

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,
    ),
);
Source

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()
}));
Source

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()
}));
Source

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()));
Source

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()));
Source

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()));
Source

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()));

Trait Implementations§

Source§

impl<'a> Clone for Doc<'a>

Source§

fn clone(&self) -> Doc<'a>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a> Debug for Doc<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for Doc<'a>

§

impl<'a> RefUnwindSafe for Doc<'a>

§

impl<'a> !Send for Doc<'a>

§

impl<'a> !Sync for Doc<'a>

§

impl<'a> Unpin for Doc<'a>

§

impl<'a> UnwindSafe for Doc<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.