FmtContext

Trait FmtContext 

Source
pub trait FmtContext<P> {
    // Required methods
    fn line_length(&self, line: usize) -> usize;
    fn fmt_line(&self, f: &mut dyn Write, line: usize) -> Result;

    // Provided methods
    fn fmt_context_single_line(
        &self,
        f: &mut dyn Write,
        start: &P,
        num_cols: usize,
    ) -> Result
       where P: UserPosn { ... }
    fn fmt_context_multiple_lines(
        &self,
        f: &mut dyn Write,
        start: &P,
        end: &P,
    ) -> Result
       where P: UserPosn { ... }
    fn fmt_context(&self, fmt: &mut dyn Write, start: &P, end: &P) -> Result
       where P: UserPosn { ... }
}
Expand description

This trait is provided by types that wish to support context for (e.g.) error messages

It requires the type to have the ability to map from a line number to a position within the file/stream/text of the type, and to provide the length of any specific line nummber.e

With those supplied methods, the trait provides the ‘fmt_context’ method, which outputs to a formatter (which can be an &mut String even) the lines of the text ahead of a provided span of start and end positions within the stream.

Currently the format of the context is fixed - the number of lines ahead is fixed a a maximum of four, the lines are always numbered with aa line number of up to 4 digits, and so on.

Required Methods§

Source

fn line_length(&self, line: usize) -> usize

Return the length of the specified line

Source

fn fmt_line(&self, f: &mut dyn Write, line: usize) -> Result

Format the line of text (potentially with coloring and so on).

This formatting must preserve the columnn numbers of characters if context markers are to line up correctly

Provided Methods§

Source

fn fmt_context_single_line( &self, f: &mut dyn Write, start: &P, num_cols: usize, ) -> Result
where P: UserPosn,

Format a line of text with highlight on certain columns

Source

fn fmt_context_multiple_lines( &self, f: &mut dyn Write, start: &P, end: &P, ) -> Result
where P: UserPosn,

Format multiple lines of text, highlighting certain lines

Source

fn fmt_context(&self, fmt: &mut dyn Write, start: &P, end: &P) -> Result
where P: UserPosn,

Format text with highlighting between start and end

This is the main method used by clients of the trait

Examples found in repository?
examples/calc.rs (line 171)
151fn main() -> Result<(), String> {
152    let args: Vec<String> = env::args().collect();
153    if args.len() < 2 {
154        return Err(format!("Usage: {} <expression>", args[0]));
155    }
156    let args_as_string = args[1..].join(" ");
157    let c = CalcTokenParser::new();
158    let l = LexerOfString::default().set_text(args_as_string);
159    let ts = l.lexer();
160
161    // let ts = TextStream::new(&args_as_string);
162
163    println!("Parsing");
164    let tokens = c.iter(&ts);
165    for t in tokens {
166        let t = {
167            match t {
168                Err(e) => {
169                    println!();
170                    let mut s = String::new();
171                    l.fmt_context(&mut s, &e.pos, &e.pos).unwrap();
172                    eprintln!("{}", s);
173                    return Err(format!("{}", e));
174                }
175                Ok(t) => t,
176            }
177        };
178        print!("{}", t);
179    }
180    println!();
181    println!("Text parsed okay");
182    Ok(())
183}
More examples
Hide additional examples
examples/simple.rs (line 225)
201fn main() -> Result<(), String> {
202    let args: Vec<String> = env::args().collect();
203    if args.len() < 2 {
204        return Err(format!("Usage: {} <expression>", args[0]));
205    }
206    let args_as_string = args[1..].join(" ");
207
208    let mut parsers = ParserVec::new();
209    parsers.add_parser(|a, b, c| LexToken::parse_whitespace(a, b, c));
210    parsers.add_parser(|a, b, c| LexToken::parse_comment_line(a, b, c));
211    parsers.add_parser(|a, b, c| LexToken::parse_digits(a, b, c));
212    parsers.add_parser(|a, b, c| LexToken::parse_char(a, b, c));
213
214    let l = LexerOfString::default().set_text(args_as_string);
215    let ts = l.lexer();
216    let tokens = ts.iter(&parsers.parsers);
217
218    println!("Parsing");
219    for t in tokens {
220        let t = {
221            match t {
222                Err(e) => {
223                    println!();
224                    let mut s = String::new();
225                    l.fmt_context(&mut s, &e.pos, &e.pos).unwrap();
226                    eprintln!("{}", s);
227                    return Err(format!("{}", e));
228                }
229                Ok(t) => t,
230            }
231        };
232        println!("{:?}", t);
233    }
234    println!();
235    println!("Text parsed okay");
236    Ok(())
237}

Implementors§

Source§

impl<P, T, E> FmtContext<P> for LexerOfString<P, T, E>
where P: PosnInCharStream, E: LexerError<P>,