Crate byte_parser[][src]

Byte Parser

A library that provides a functional way to easely parse a string or a slice.

Basic Example

use byte_parser::{StrParser, ParseIterator};

let mut parser = StrParser::new("\
	key: value\n\
	other key: more : value\n\
	also valid\
");

let lines: Vec<(&str, &str)> = parser
	.split_on_byte(b'\n')
	.map_and_collect(|line| {

		let key = line
			.record()
			.consume_while_byte_fn(|&b| b != b':')
			.to_str();

		let has_colon = line.advance().is_some();
		if !has_colon {
			return ("", key.trim_start());
		}

		let value = line
			.record()
			.consume_to_str();

		(key, value.trim_start())
	});

assert_eq!(lines[0], ("key", "value"));
assert_eq!(lines[1], ("other key", "more : value"));
assert_eq!(lines[2], ("", "also valid"));

Example parsing a number

use byte_parser::{StrParser, ParseIterator};

#[derive(Debug, PartialEq)]
pub enum Number {
	Uint(usize),
	Integer(isize),
	Float(f32)
}

impl Number {
	/// # Panics
	/// Panics if invalid utf8 is found.
	/// Or if the digit is to large.
	pub fn from_parser<'s, I>(iter: &mut I) -> Option<Self>
	where I: ParseIterator<'s> {
		let mut iter = iter.record();

		// there could be a leading minus -
		let is_negative = iter
			.next_if(|&b| b == b'-')
			.is_some();

		// consume first digits
		iter
			.while_byte_fn(u8::is_ascii_digit)
			.consume_at_least(1)
			.ok()?;
			
		// there could be a dot
		let has_dot = iter
			.next_if(|&b| b == b'.')
			.is_some();

		if !has_dot {
			let s = iter.to_str();
			let num = match is_negative {
				true => Self::Integer(
					s.parse().expect("digit to large")
				),
				false => Self::Uint(
					s.parse().expect("digit to large")
				)
			};

			return Some(num)
		}

		// consume next digits
		iter.consume_while_byte_fn(u8::is_ascii_digit);

		Some(Self::Float(
			iter.to_str().parse().expect("digit to large")
		))
	}
}

impl FromStr for Number {
	type Err = ();
	fn from_str(s: &str) -> Result<Self, ()> {
		let mut parser = StrParser::new(s);
		let num = Self::from_parser(&mut parser)
			.ok_or(())?;

		// parser not exhausted
		if parser.advance().is_some() {
			return Err(())
		}

		Ok(num)
	}
}

assert_eq!(Number::Float(1.23), "1.23".parse().unwrap());
assert_eq!(Number::Float(-32.1), "-32.1".parse().unwrap());
assert_eq!(Number::Uint(420), "420".parse().unwrap());
assert_eq!(Number::Integer(-42), "-42".parse().unwrap());
assert!(".42".parse::<Number>().is_err());
assert!("5.42 ".parse::<Number>().is_err());

Modules

ignore_byte
parse_iterunstable-parse-iter
pit
position
recorder
split_on_byte

Splits the iterator at a given byte.

stop
while_byte_fn

Structs

Parser

ParseIterator implementation for a slice.

StrParser

ParseIterator implementation for a str.

Traits

ExpectByte
ParseIterator

The main trait of this crate.

Functions

parse_iterunstable-parse-iter

From a ParseIterator generate an Iterator.