4 releases

0.2.1 May 24, 2019
0.2.0 May 24, 2019
0.1.1 Mar 30, 2019
0.1.0 Mar 30, 2019

#2269 in Parser implementations


Used in 2 crates

MIT license

16KB
217 lines

text-reader

Build Status

Rust string character reader.

Usage

[dependencies]
text-reader = "0.2"

Examples

TextReader

use text_reader::TextReader;

#[test]
fn test_while() {
  let mut reader = TextReader::new("華文\ndef");
  while reader.has_next() {
    let position = reader.position();
    match reader.next() {
      Some(ch) => match position {
        0 => assert_eq!('', ch),
        1 => assert_eq!('', ch),
        2 => assert_eq!('\n', ch),
        3 => assert_eq!('d', ch),
        4 => assert_eq!('e', ch),
        5 => assert_eq!('f', ch),
        _ => {}
      },
      None => panic!("None")
    }
  }
}

TextReader and Detector

#[test]
fn test_detector() {
  let text = r#"
{"type": "typeA", "name": "Earth", "continent": ["Asia", "Europe"]}
  "#;
  let mut reader = TextReader::new(text);
  let mut rets = Vec::new();
  while reader.has_next() {
    match reader.next() {
      Some('"') => {
        let mut detector = reader.detector();
        rets.push('"');
        if detector.next_text("type").yes() {
          detector.rollback();
          rets.push('t');
        }
        continue;
      },
      Some(ch) => {
        rets.push(ch);
        continue;
      }
      None => {}
    }
  }
  let ret = rets.iter().collect::<String>();
  println!("{}", ret);
}

more

more

Analysis

use text_reader::TextReader;

#[test]
fn test_stat() {
  let mut reader = TextReader::new("abc\ndef");
  println!("{:?}", reader);
  reader.next();
  println!("{:?}", reader);
  reader.back();
  println!("{:?}", reader);
  let line_text = reader.this_line();
  println!("{:?}", line_text);
  let position = reader.position();
  println!("{:?}", position);
  println!("{:?}", reader);

  reader.next();
  reader.next();
  reader.next();
  let line = reader.line(); // 1
  assert_eq!(1, line);
  println!("{:?}", reader);
  reader.next();
  let line = reader.line(); // 2
  assert_eq!(2, line);
  println!("{:?}", reader);
}

When create a TextReader TextReader::new("abc\ndef"), TextReader status is:

TextReader { len: 7, text: ['a', 'b', 'c', '\n', 'd', 'e', 'f'], position: 0, line: 1, cursor: 0 }

next

And then, read next character let ch = reader.next(), ch will return Some('a'); TextReader status:

TextReader { len: 7, text: ['a', 'b', 'c', '\n', 'd', 'e', 'f'], position: 1, line: 1, cursor: 1 }

peek

peek function not change status, only get current character let ch = reader.peek()

TextReader { len: 7, text: ['a', 'b', 'c', '\n', 'd', 'e', 'f'], position: 1, line: 1, cursor: 1 }

back

Back will change TextReader to previous status. return TextReader reference. reader.back().

TextReader { len: 7, text: ['a', 'b', 'c', '\n', 'd', 'e', 'f'], position: 0, line: 1, cursor: 0 }

this_line

this line return current line text, not change TextReader status. let line_text = reader.this_line().

TextReader { len: 7, text: ['a', 'b', 'c', '\n', 'd', 'e', 'f'], position: 0, line: 1, cursor: 0 }

line_text is Some("abc")

position

position function return TextReader position value. the num of character position. let position = reader.position()

position is 0

TextReader { len: 7, text: ['a', 'b', 'c', '\n', 'd', 'e', 'f'], position: 0, line: 1, cursor: 0 }

line

return current line number, split of \n.

reader.next();
reader.next();
reader.next();
let line = reader.line(); // 1
// TextReader { len: 7, text: ['a', 'b', 'c', '\n', 'd', 'e', 'f'], position: 3, line: 1, cursor: 3 }
reader.next();
let line = reader.line(); // 2
// TextReader { len: 7, text: ['a', 'b', 'c', '\n', 'd', 'e', 'f'], position: 4, line: 2, cursor: 0 }

cursor

position of line. starting from 0. and change to 0 when it encounters \n

has_next

has next character. can be used with while. or determine if the last character

No runtime deps