Skip to main content

SnippetBuilder

Struct SnippetBuilder 

Source
pub struct SnippetBuilder { /* private fields */ }
Expand description

Incrementally constructs a Snippet.

This type is the low-level building block that allows to create snippets in a custom way, with more flexibility than the convenience methods of Snippet.

Every time you push something into the builder you must tell it how many source units that rendered fragment corresponds to. That is the orig_len parameter accepted by next_line() and the push_* methods.

If you want a fragment to be addressable individually by a span, push it with its own push_* call. For example, if you call push_str("abc", 3, false), any span that covers any of those three units will cover the entire rendered "abc" fragment.

Most push_* methods also accept an alt flag. When alt is true, the appended fragment is recorded as “alternate” text. This is intended for replacement/escaped representations (for example, <XX> escapes for control characters or invalid bytes) so it can be rendered differently (e.g., highlighted).

§Example

/// Builds a snippet from UTF-8
///
/// `"\n"` and `"\r\n"` are treated as line breaks and tabs are expanded to
/// 4 spaces. Control characters are represented with `<U+XXXX>`.
fn build_snippet(source: &str) -> sourceannot::Snippet {
    let mut builder = sourceannot::Snippet::builder(1);
    let mut chars = source.chars();

    if let Some(mut cur_chr) = chars.next() {
        loop {
            let mut next_chr = chars.next();
            if cur_chr == '\r' && next_chr == Some('\n') {
                builder.next_line(2);
                next_chr = chars.next();
            } else if cur_chr == '\n' {
                builder.next_line(1);
            } else if cur_chr == '\t' {
                // Equivalent to `builder.push_str("    ", 1, false);`
                builder.push_spaces(4, 1, false);
            } else if sourceannot::char_should_be_replaced(cur_chr) {
                builder.push_fmt(
                    format_args!("<U+{:04X}>", u32::from(cur_chr)),
                    cur_chr.len_utf8(),
                    true,
                );
            } else {
                builder.push_char(cur_chr, cur_chr.len_utf8(), false);
            }

            cur_chr = match next_chr {
                Some(c) => c,
                None => break,
            };
        }
    }

    builder.finish()
}

let snippet = build_snippet("Hello world");

Implementations§

Source§

impl SnippetBuilder

Source

pub fn finish(self) -> Snippet

Finalizes the builder and returns the constructed Snippet.

Source

pub fn next_line(&mut self, orig_len: usize)

Ends the current line and starts a new one.

orig_len is the number of source units consumed by the line break. For example, it can be 1 for "\n" or 2 for "\r\n".

Source

pub fn push_empty(&mut self, orig_len: usize)

Consumes orig_len source units without producing any rendered text.

This is useful when you need to “eat” units that should not be visible in the output but still need to be span-addressable.

Source

pub fn push_str(&mut self, text: &str, orig_len: usize, alt: bool)

Appends text to the current line.

Source

pub fn push_char(&mut self, chr: char, orig_len: usize, alt: bool)

Appends a single character to the current line.

Source

pub fn push_spaces(&mut self, width: usize, orig_len: usize, alt: bool)

Appends width ASCII spaces to the current line.

Source

pub fn push_fmt(&mut self, args: Arguments<'_>, orig_len: usize, alt: bool)

Writes formatted text to the current line.

Auto Trait Implementations§

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> 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, 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.