svgparser 0.8.1

Featureful, pull-based, zero-allocation SVG parser.
Documentation
extern crate svgparser;

use svgparser::{
    xmlparser,
    Length,
    LengthUnit,
    StreamExt,
};

use xmlparser::{
    Stream,
};

macro_rules! test_number {
    ($name:ident, $text:expr, $result:expr) => (
        #[test]
        fn $name() {
            let mut s = Stream::from_str($text);
            assert_eq!(s.parse_number().unwrap(), $result);
        }
    )
}

test_number!(number_1,  "0", 0.0);
test_number!(number_2,  "1", 1.0);
test_number!(number_3,  "-1", -1.0);
test_number!(number_4,  " -1 ", -1.0);
test_number!(number_5,  "  1  ", 1.0);
test_number!(number_6,  ".4", 0.4);
test_number!(number_7,  "-.4", -0.4);
test_number!(number_8,  "-.4text", -0.4);
test_number!(number_9,  "-.01 text", -0.01);
test_number!(number_10, "-.01 4", -0.01);
test_number!(number_11, ".0000000000008", 0.0000000000008);
test_number!(number_12, "1000000000000", 1000000000000.0);
test_number!(number_13, "123456.123456", 123456.123456);
test_number!(number_14, "+10", 10.0);
test_number!(number_15, "1e2", 100.0);
test_number!(number_16, "1e+2", 100.0);
test_number!(number_17, "1E2", 100.0);
test_number!(number_18, "1e-2", 0.01);
test_number!(number_19, "1ex", 1.0);
test_number!(number_20, "1em", 1.0);
test_number!(number_21, "12345678901234567890", 12345678901234567000.0);
test_number!(number_22, "0.", 0.0);
test_number!(number_23, "1.3e-2", 0.013);
// test_number!(number_24, "1e", 1.0); // TODO: this

// ---

macro_rules! test_number_err {
    ($name:ident, $text:expr, $result:expr) => (
        #[test]
        fn $name() {
            let mut s = Stream::from_str($text);
            assert_eq!(s.parse_number().unwrap_err().to_string(), $result);
        }
    )
}

test_number_err!(number_err_1, "q",    "invalid number at 1:1");
test_number_err!(number_err_2, "",     "invalid number at 1:1");
test_number_err!(number_err_3, "-",    "invalid number at 1:1");
test_number_err!(number_err_4, "+",    "invalid number at 1:1");
test_number_err!(number_err_5, "-q",   "invalid number at 1:1");
test_number_err!(number_err_6, ".",    "invalid number at 1:1");
test_number_err!(number_err_7, "99999999e99999999",  "invalid number at 1:1");
test_number_err!(number_err_8, "-99999999e99999999", "invalid number at 1:1");

// ---

macro_rules! test_length {
    ($name:ident, $text:expr, $result:expr) => (
        #[test]
        fn $name() {
            let mut s = Stream::from_str($text);
            assert_eq!(s.parse_length().unwrap(), $result);
        }
    )
}

test_length!(length_1,  "1",   Length::new(1.0, LengthUnit::None));
test_length!(length_2,  "1em", Length::new(1.0, LengthUnit::Em));
test_length!(length_3,  "1ex", Length::new(1.0, LengthUnit::Ex));
test_length!(length_4,  "1px", Length::new(1.0, LengthUnit::Px));
test_length!(length_5,  "1in", Length::new(1.0, LengthUnit::In));
test_length!(length_6,  "1cm", Length::new(1.0, LengthUnit::Cm));
test_length!(length_7,  "1mm", Length::new(1.0, LengthUnit::Mm));
test_length!(length_8,  "1pt", Length::new(1.0, LengthUnit::Pt));
test_length!(length_9,  "1pc", Length::new(1.0, LengthUnit::Pc));
test_length!(length_10, "1%",  Length::new(1.0, LengthUnit::Percent));
test_length!(length_11, "1,",  Length::new(1.0, LengthUnit::None));
test_length!(length_12, "1 ,", Length::new(1.0, LengthUnit::None));
test_length!(length_13, "1 1", Length::new(1.0, LengthUnit::None));
test_length!(length_14, "1e0", Length::new(1.0, LengthUnit::None));
test_length!(length_15, "1.0e0", Length::new(1.0, LengthUnit::None));
test_length!(length_16, "1.0e0em", Length::new(1.0, LengthUnit::Em));

#[test]
fn length_err_1() {
    let mut s = Stream::from_str("1q");
    assert_eq!(s.parse_length().unwrap(), Length::new(1.0, LengthUnit::None));
    assert_eq!(s.parse_length().unwrap_err().to_string(),
               "invalid number at 1:2");
}

// ---

#[test]
fn integer_1() {
    let mut s = Stream::from_str("10");
    assert_eq!(s.parse_integer().unwrap(), 10);
}

#[test]
fn integer_err_1() {
    // error because of overflow
    let mut s = Stream::from_str("10000000000000");
    assert_eq!(s.parse_integer().unwrap_err().to_string(),
               "invalid number at 1:1");
}