2 releases

0.1.1 Aug 9, 2023
0.1.0 Aug 7, 2023

#1617 in Text processing

MIT license

19KB
226 lines

TextBlocks

Rust Release Dependency status crates.io Downloads crates.io

A simple crate for parsing text blocks. Can be used to parse text files with blocks of data separated by blank lines. Works well with \n or \r\n line endings.

Contains the TextBlocks trait which adds the methods as_blocks, block_parse_lines and block_parse to str and String.

Install

Run the following command in your project directory:

cargo add textblocks

Or add the following to your Cargo.toml:

[dependencies]
textblocks = "0.1.0"

Check the crates.io page for the latest version.

Usage

To parse text into blocks, you need to provide a block delimiter, a line parser and a block parser.

  • The block delimiter is a string that separates blocks. The default is a blank line (double newline), but you can use any string.
    • BlockDelimiter::DoubleLineGeneric (the default) will use "\r\n\r\n" if the string contains "\r\n" newlines, otherwise "\n\n".
    • BlockDelimiter::Delimiter(s) will use s (a String) as the delimiter.
  • The line parser is any function or closure that takes a &str and returns a value of type T. The final result will be a Vec<Vec<T>>. You can use the block_parse_lines method if you don't need a block parser and only want to parse the lines.
  • The block parser is any function or closure that takes a &[T] and returns a value of type U. The final result will be a Vec<U>.

Examples

  • Parse a block into a vector of lines

[!IMPORTANT] This will allocate a vector of vectors of &str. If you want to avoid these allocations, use block_parse_lines or block_parse. In that case, A vector will only be allocated for the requested result type.

use textblocks::*;
let s = "100\n200\n\n300\n400\n\n500\n600";
let block_delimiter = BlockDelimiter::DoubleLineGeneric;
assert_eq!(s.as_blocks(&block_delimiter), vec![vec!["100", "200"], vec!["300", "400"], vec!["500", "600"]]);
assert_eq!(s.as_blocks(&block_delimiter), [["100", "200"], ["300", "400"], ["500", "600"]]);
  • Parse a block into a vector of lines, where each line is parsed into a number (u32)
use textblocks::*;
let s = "100\n200\n\n300\n400\n\n500\n600";
let block_delimiter = BlockDelimiter::DoubleLineGeneric;
let result = s.block_parse_lines(&block_delimiter,|line| line.parse::<u32>().unwrap());
assert_eq!(result, [[100, 200], [300, 400], [500, 600]]);
  • Parse a block into a vector of lines, where each line is parsed into a number (u32), and then sum the numbers
use textblocks::*;
let s = "100\n200\n\n300\n400\n\n500\n600";
let block_delimiter = BlockDelimiter::DoubleLineGeneric;
let result = s.block_parse(
    &block_delimiter,
    |line| line.parse::<u32>().unwrap(),
    |block| block.iter().sum::<u32>()
);
assert_eq!(result, [300, 700, 1100]);

No runtime deps