#[macro_use]
extern crate error_chain;
#[cfg(test)]
#[macro_use]
extern crate assert_matches;
mod error;
mod parser;
pub use error::{Error, ErrorKind};
pub use parser::{validate, Success};
#[cfg(test)]
mod tests {
use error::{Error, ErrorKind};
use parser::{self, Success};
const V1: [u8; 1] = [0x00];
const V2: [u8; 1] = [0x14];
const V3: [u8; 1] = [0x7F];
const V4: [u8; 2] = [0xc2, 0x80];
const V5: [u8; 2] = [0xc2, 0xa2];
const V6: [u8; 2] = [0xdf, 0xbf];
const V7: [u8; 3] = [0xe0, 0xa0, 0x80];
const V8: [u8; 3] = [0xe2, 0x82, 0xac];
const V9: [u8; 3] = [0xef, 0xbf, 0xbf];
const V10: [u8; 4] = [0xf0, 0x90, 0x80, 0x80];
const V11: [u8; 4] = [0xf0, 0x90, 0x8d, 0x88];
const V12: [u8; 4] = [0xf4, 0x8f, 0xbf, 0xbf];
const C1: [u8; 2] = [0xc0, 0x00];
const C2: [u8; 2] = [0xc0, 0x7f];
const C3: [u8; 2] = [0xc0, 0xc0];
const C4: [u8; 2] = [0xc0, 0xff];
const C5: [u8; 3] = [0xe0, 0x00, 0x80];
const C6: [u8; 3] = [0xe0, 0x7f, 0x80];
const C7: [u8; 3] = [0xe0, 0xc0, 0x80];
const C8: [u8; 3] = [0xe0, 0xff, 0x80];
const C9: [u8; 3] = [0xe0, 0x80, 0x00];
const C10: [u8; 3] = [0xe0, 0x80, 0x7f];
const C11: [u8; 3] = [0xe0, 0x80, 0xc0];
const C12: [u8; 3] = [0xe0, 0x80, 0xff];
const C13: [u8; 4] = [0xf0, 0x00, 0x80, 0x80];
const C14: [u8; 4] = [0xf0, 0x7f, 0x80, 0x80];
const C15: [u8; 4] = [0xf0, 0xc0, 0x80, 0x80];
const C16: [u8; 4] = [0xf0, 0xff, 0x80, 0x80];
const C17: [u8; 4] = [0xf0, 0x80, 0x00, 0x80];
const C18: [u8; 4] = [0xf0, 0x80, 0x7f, 0x80];
const C19: [u8; 4] = [0xf0, 0x80, 0xc0, 0x80];
const C20: [u8; 4] = [0xf0, 0x80, 0xff, 0x80];
const C21: [u8; 4] = [0xf0, 0x80, 0x80, 0x00];
const C22: [u8; 4] = [0xf0, 0x80, 0x80, 0x7f];
const C23: [u8; 4] = [0xf0, 0x80, 0x80, 0xc0];
const C24: [u8; 4] = [0xf0, 0x80, 0x80, 0xff];
const O1: [u8; 2] = [0xc0, 0x80];
const O2: [u8; 2] = [0xc1, 0xbf];
const O3: [u8; 3] = [0xe0, 0x80, 0x80];
const O4: [u8; 3] = [0xe0, 0x9f, 0xbf];
const O5: [u8; 4] = [0xf0, 0x80, 0x80, 0x80];
const O6: [u8; 4] = [0xf0, 0x8f, 0xbf, 0xbf];
const I1: [u8; 4] = [0xf4, 0x90, 0x80, 0x80];
const I2: [u8; 3] = [0xed, 0xa0, 0x80];
const I3: [u8; 3] = [0xed, 0xad, 0xbf];
const I4: [u8; 3] = [0xed, 0xae, 0x80];
const I5: [u8; 3] = [0xed, 0xaf, 0xbf];
const I6: [u8; 3] = [0xed, 0xb0, 0x80];
const I7: [u8; 3] = [0xed, 0xbe, 0x80];
const I8: [u8; 3] = [0xed, 0xbf, 0xbf];
const FAIL_FASTER: [u8; 21] = [0xce, 0xba, 0xe1, 0xbd, 0xb9, 0xcf, 0x83, 0xce, 0xbc, 0xce,
0xb5, 0xf4, 0x90, 0x80, 0x80, 0x65, 0x64, 0x69, 0x74, 0x65,
0x64];
macro_rules! putf8(
($n:ident, $a:expr, $b:expr, $pat:pat) => {
#[test]
fn $n() {
let expected = $a;
let res = parser::validate(&expected);
if $b {
assert!(res.is_ok());
} else {
assert!(res.is_err());
}
assert_matches!(res, $pat);
}
}
);
putf8!(greater_than_max_code_point,
vec![0xf5],
false,
Err(Error(ErrorKind::BeyondMaximumCodePoint, _)));
putf8!(fail_at_first_invalid_byte,
FAIL_FASTER,
false,
Err(Error(ErrorKind::BeyondMaximumCodePoint, _)));
putf8!(two_byte_continuation_0x00,
C1,
false,
Err(Error(ErrorKind::TwoByteContinuation, _)));
putf8!(two_byte_continuation_0x7f,
C2,
false,
Err(Error(ErrorKind::TwoByteContinuation, _)));
putf8!(two_byte_continuation_0xc0,
C3,
false,
Err(Error(ErrorKind::TwoByteContinuation, _)));
putf8!(two_byte_continuation_0xff,
C4,
false,
Err(Error(ErrorKind::TwoByteContinuation, _)));
putf8!(three_byte_continuation_0x00_0x80,
C5,
false,
Err(Error(ErrorKind::ThreeByteContinuation(2), _)));
putf8!(three_byte_continuation_0x7f_0x80,
C6,
false,
Err(Error(ErrorKind::ThreeByteContinuation(2), _)));
putf8!(three_byte_continuation_0xc0_0x80,
C7,
false,
Err(Error(ErrorKind::ThreeByteContinuation(2), _)));
putf8!(three_byte_continuation_0xff_0x80,
C8,
false,
Err(Error(ErrorKind::ThreeByteContinuation(2), _)));
putf8!(three_byte_continuation_0x80_0x00,
C9,
false,
Err(Error(ErrorKind::ThreeByteContinuation(3), _)));
putf8!(three_byte_continuation_0x80_0x7f,
C10,
false,
Err(Error(ErrorKind::ThreeByteContinuation(3), _)));
putf8!(three_byte_continuation_0x80_0xc0,
C11,
false,
Err(Error(ErrorKind::ThreeByteContinuation(3), _)));
putf8!(three_byte_continuation_0x80_0xff,
C12,
false,
Err(Error(ErrorKind::ThreeByteContinuation(3), _)));
putf8!(four_byte_continuation_0x00_0x80_0x80,
C13,
false,
Err(Error(ErrorKind::FourByteContinuation(2), _)));
putf8!(four_byte_continuation_0x7f_0x80_0x80,
C14,
false,
Err(Error(ErrorKind::FourByteContinuation(2), _)));
putf8!(four_byte_continuation_0xc0_0x80_0x80,
C15,
false,
Err(Error(ErrorKind::FourByteContinuation(2), _)));
putf8!(four_byte_continuation_0xff_0x80_0x80,
C16,
false,
Err(Error(ErrorKind::FourByteContinuation(2), _)));
putf8!(four_byte_continuation_0x80_0x00_0x80,
C17,
false,
Err(Error(ErrorKind::FourByteContinuation(3), _)));
putf8!(four_byte_continuation_0x80_0x7f_0x80,
C18,
false,
Err(Error(ErrorKind::FourByteContinuation(3), _)));
putf8!(four_byte_continuation_0x80_0xc0_0x80,
C19,
false,
Err(Error(ErrorKind::FourByteContinuation(3), _)));
putf8!(four_byte_continuation_0x80_0xff_0x80,
C20,
false,
Err(Error(ErrorKind::FourByteContinuation(3), _)));
putf8!(four_byte_continuation_0x80_0x80_0x00,
C21,
false,
Err(Error(ErrorKind::FourByteContinuation(4), _)));
putf8!(four_byte_continuation_0x80_0x80_0x7f,
C22,
false,
Err(Error(ErrorKind::FourByteContinuation(4), _)));
putf8!(four_byte_continuation_0x80_0x80_0xc0,
C23,
false,
Err(Error(ErrorKind::FourByteContinuation(4), _)));
putf8!(four_byte_continuation_0x80_0x80_0xff,
C24,
false,
Err(Error(ErrorKind::FourByteContinuation(4), _)));
putf8!(smallest_two_byte_overlong,
O1,
false,
Err(Error(ErrorKind::TwoByteOverlong, _)));
putf8!(largest_two_byte_overlong,
O2,
false,
Err(Error(ErrorKind::TwoByteOverlong, _)));
putf8!(smallest_three_byte_overlong,
O3,
false,
Err(Error(ErrorKind::ThreeByteOverlong, _)));
putf8!(largest_three_byte_overlong,
O4,
false,
Err(Error(ErrorKind::ThreeByteOverlong, _)));
putf8!(smallest_four_byte_overlong,
O5,
false,
Err(Error(ErrorKind::FourByteOverlong, _)));
putf8!(largest_four_byte_overlong,
O6,
false,
Err(Error(ErrorKind::FourByteOverlong, _)));
putf8!(invalid_first_byte,
vec![0x80],
false,
Err(Error(ErrorKind::InvalidFirstByte(0x80), _)));
putf8!(one_larger_than_maximum_code_point,
I1,
false,
Err(Error(ErrorKind::BeyondMaximumCodePoint, _)));
putf8!(utf16_surrogate_1,
I2,
false,
Err(Error(ErrorKind::UTF16Surrogate, _)));
putf8!(utf16_surrogate_2,
I3,
false,
Err(Error(ErrorKind::UTF16Surrogate, _)));
putf8!(utf16_surrogate_3,
I4,
false,
Err(Error(ErrorKind::UTF16Surrogate, _)));
putf8!(utf16_surrogate_4,
I5,
false,
Err(Error(ErrorKind::UTF16Surrogate, _)));
putf8!(utf16_surrogate_5,
I6,
false,
Err(Error(ErrorKind::UTF16Surrogate, _)));
putf8!(utf16_surrogate_6,
I7,
false,
Err(Error(ErrorKind::UTF16Surrogate, _)));
putf8!(utf16_surrogate_7,
I8,
false,
Err(Error(ErrorKind::UTF16Surrogate, _)));
putf8!(empty, vec![], true, Ok(Success::Complete(0)));
putf8!(incomplete_two_byte,
vec![0xc2],
true,
Ok(Success::Incomplete(1, 0)));
putf8!(incomplete_two_byte_after_one_byte,
vec![0x24, 0xc2],
true,
Ok(Success::Incomplete(1, 1)));
putf8!(incomplete_two_after_two_byte,
vec![0xc2, 0xa2, 0xc2],
true,
Ok(Success::Incomplete(1, 2)));
putf8!(smallest_one_byte_code_point,
V1,
true,
Ok(Success::Complete(1)));
putf8!(valid_one_byte_code_point,
V2,
true,
Ok(Success::Complete(1)));
putf8!(largest_one_byte_code_point,
V3,
true,
Ok(Success::Complete(1)));
putf8!(smallest_two_byte_code_point,
V4,
true,
Ok(Success::Complete(2)));
putf8!(valid_two_byte_code_point,
V5,
true,
Ok(Success::Complete(2)));
putf8!(largest_two_byte_code_point,
V6,
true,
Ok(Success::Complete(2)));
putf8!(smallest_three_byte_code_point,
V7,
true,
Ok(Success::Complete(3)));
putf8!(valid_three_byte_code_point,
V8,
true,
Ok(Success::Complete(3)));
putf8!(largest_three_byte_code_point,
V9,
true,
Ok(Success::Complete(3)));
putf8!(smallest_four_byte_code_point,
V10,
true,
Ok(Success::Complete(4)));
putf8!(valid_four_byte_code_point,
V11,
true,
Ok(Success::Complete(4)));
putf8!(largest_four_byte_code_point,
V12,
true,
Ok(Success::Complete(4)));
}