1//! Character specific parsers and combinators, complete input version. 2//! 3//! Functions recognizing specific characters. 4 5use crate::branch::alt; 6use crate::combinator::opt; 7use crate::error::ErrorKind; 8use crate::error::ParseError; 9use crate::internal::{Err, IResult}; 10use crate::lib::std::ops::{Range, RangeFrom, RangeTo}; 11use crate::traits::{ 12 AsChar, FindToken, InputIter, InputLength, InputTake, InputTakeAtPosition, Slice, 13}; 14use crate::traits::{Compare, CompareResult}; 15 16/// Recognizes one character. 17/// 18/// *Complete version*: Will return an error if there's not enough input data. 19/// # Example 20/// 21/// ``` 22/// # use nom::{Err, error::{ErrorKind, Error}, IResult}; 23/// # use nom::character::complete::char; 24/// fn parser(i: &str) -> IResult<&str, char> { 25/// char('a')(i) 26/// } 27/// assert_eq!(parser("abc"), Ok(("bc", 'a'))); 28/// assert_eq!(parser(" abc"), Err(Err::Error(Error::new(" abc", ErrorKind::Char)))); 29/// assert_eq!(parser("bc"), Err(Err::Error(Error::new("bc", ErrorKind::Char)))); 30/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Char)))); 31/// ``` 32pub fn char<I, Error: ParseError<I>>(c: char) -> impl Fn(I) -> IResult<I, char, Error> 33where 34 I: Slice<RangeFrom<usize>> + InputIter, 35 <I as InputIter>::Item: AsChar, 36{ 37 move |i: I| match (i).iter_elements().next().map(|t| { 38 let b = t.as_char() == c; 39 (&c, b) 40 }) { 41 Some((c, true)) => Ok((i.slice(c.len()..), c.as_char())), 42 _ => Err(Err::Error(Error::from_char(i, c))), 43 } 44} 45 46/// Recognizes one character and checks that it satisfies a predicate 47/// 48/// *Complete version*: Will return an error if there's not enough input data. 49/// # Example 50/// 51/// ``` 52/// # use nom::{Err, error::{ErrorKind, Error}, Needed, IResult}; 53/// # use nom::character::complete::satisfy; 54/// fn parser(i: &str) -> IResult<&str, char> { 55/// satisfy(|c| c == 'a' || c == 'b')(i) 56/// } 57/// assert_eq!(parser("abc"), Ok(("bc", 'a'))); 58/// assert_eq!(parser("cd"), Err(Err::Error(Error::new("cd", ErrorKind::Satisfy)))); 59/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Satisfy)))); 60/// ``` 61pub fn satisfy<F, I, Error: ParseError<I>>(cond: F) -> impl Fn(I) -> IResult<I, char, Error> 62where 63 I: Slice<RangeFrom<usize>> + InputIter, 64 <I as InputIter>::Item: AsChar, 65 F: Fn(char) -> bool, 66{ 67 move |i: I| match (i).iter_elements().next().map(|t| { 68 let c = t.as_char(); 69 let b = cond(c); 70 (c, b) 71 }) { 72 Some((c, true)) => Ok((i.slice(c.len()..), c)), 73 _ => Err(Err::Error(Error::from_error_kind(i, ErrorKind::Satisfy))), 74 } 75} 76 77/// Recognizes one of the provided characters. 78/// 79/// *Complete version*: Will return an error if there's not enough input data. 80/// # Example 81/// 82/// ``` 83/// # use nom::{Err, error::ErrorKind}; 84/// # use nom::character::complete::one_of; 85/// assert_eq!(one_of::<_, _, (&str, ErrorKind)>("abc")("b"), Ok(("", 'b'))); 86/// assert_eq!(one_of::<_, _, (&str, ErrorKind)>("a")("bc"), Err(Err::Error(("bc", ErrorKind::OneOf)))); 87/// assert_eq!(one_of::<_, _, (&str, ErrorKind)>("a")(""), Err(Err::Error(("", ErrorKind::OneOf)))); 88/// ``` 89pub fn one_of<I, T, Error: ParseError<I>>(list: T) -> impl Fn(I) -> IResult<I, char, Error> 90where 91 I: Slice<RangeFrom<usize>> + InputIter, 92 <I as InputIter>::Item: AsChar + Copy, 93 T: FindToken<<I as InputIter>::Item>, 94{ 95 move |i: I| match (i).iter_elements().next().map(|c| (c, list.find_token(c))) { 96 Some((c, true)) => Ok((i.slice(c.len()..), c.as_char())), 97 _ => Err(Err::Error(Error::from_error_kind(i, ErrorKind::OneOf))), 98 } 99} 100 101/// Recognizes a character that is not in the provided characters. 102/// 103/// *Complete version*: Will return an error if there's not enough input data. 104/// # Example 105/// 106/// ``` 107/// # use nom::{Err, error::ErrorKind}; 108/// # use nom::character::complete::none_of; 109/// assert_eq!(none_of::<_, _, (&str, ErrorKind)>("abc")("z"), Ok(("", 'z'))); 110/// assert_eq!(none_of::<_, _, (&str, ErrorKind)>("ab")("a"), Err(Err::Error(("a", ErrorKind::NoneOf)))); 111/// assert_eq!(none_of::<_, _, (&str, ErrorKind)>("a")(""), Err(Err::Error(("", ErrorKind::NoneOf)))); 112/// ``` 113pub fn none_of<I, T, Error: ParseError<I>>(list: T) -> impl Fn(I) -> IResult<I, char, Error> 114where 115 I: Slice<RangeFrom<usize>> + InputIter, 116 <I as InputIter>::Item: AsChar + Copy, 117 T: FindToken<<I as InputIter>::Item>, 118{ 119 move |i: I| match (i).iter_elements().next().map(|c| (c, !list.find_token(c))) { 120 Some((c, true)) => Ok((i.slice(c.len()..), c.as_char())), 121 _ => Err(Err::Error(Error::from_error_kind(i, ErrorKind::NoneOf))), 122 } 123} 124 125/// Recognizes the string "\r\n". 126/// 127/// *Complete version*: Will return an error if there's not enough input data. 128/// # Example 129/// 130/// ``` 131/// # use nom::{Err, error::{Error, ErrorKind}, IResult}; 132/// # use nom::character::complete::crlf; 133/// fn parser(input: &str) -> IResult<&str, &str> { 134/// crlf(input) 135/// } 136/// 137/// assert_eq!(parser("\r\nc"), Ok(("c", "\r\n"))); 138/// assert_eq!(parser("ab\r\nc"), Err(Err::Error(Error::new("ab\r\nc", ErrorKind::CrLf)))); 139/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::CrLf)))); 140/// ``` 141pub fn crlf<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> 142where 143 T: Slice<Range<usize>> + Slice<RangeFrom<usize>>, 144 T: InputIter, 145 T: Compare<&'static str>, 146{ 147 match input.compare("\r\n") { 148 //FIXME: is this the right index? 149 CompareResult::Ok => Ok((input.slice(2..), input.slice(0..2))), 150 _ => { 151 let e: ErrorKind = ErrorKind::CrLf; 152 Err(Err::Error(E::from_error_kind(input, e))) 153 } 154 } 155} 156 157//FIXME: there's still an incomplete 158/// Recognizes a string of any char except '\r\n' or '\n'. 159/// 160/// *Complete version*: Will return an error if there's not enough input data. 161/// # Example 162/// 163/// ``` 164/// # use nom::{Err, error::{Error, ErrorKind}, IResult, Needed}; 165/// # use nom::character::complete::not_line_ending; 166/// fn parser(input: &str) -> IResult<&str, &str> { 167/// not_line_ending(input) 168/// } 169/// 170/// assert_eq!(parser("ab\r\nc"), Ok(("\r\nc", "ab"))); 171/// assert_eq!(parser("ab\nc"), Ok(("\nc", "ab"))); 172/// assert_eq!(parser("abc"), Ok(("", "abc"))); 173/// assert_eq!(parser(""), Ok(("", ""))); 174/// assert_eq!(parser("a\rb\nc"), Err(Err::Error(Error { input: "a\rb\nc", code: ErrorKind::Tag }))); 175/// assert_eq!(parser("a\rbc"), Err(Err::Error(Error { input: "a\rbc", code: ErrorKind::Tag }))); 176/// ``` 177pub fn not_line_ending<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> 178where 179 T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>, 180 T: InputIter + InputLength, 181 T: Compare<&'static str>, 182 <T as InputIter>::Item: AsChar, 183 <T as InputIter>::Item: AsChar, 184{ 185 match input.position(|item| { 186 let c = item.as_char(); 187 c == '\r' || c == '\n' 188 }) { 189 None => Ok((input.slice(input.input_len()..), input)), 190 Some(index) => { 191 let mut it = input.slice(index..).iter_elements(); 192 let nth = it.next().unwrap().as_char(); 193 if nth == '\r' { 194 let sliced = input.slice(index..); 195 let comp = sliced.compare("\r\n"); 196 match comp { 197 //FIXME: calculate the right index 198 CompareResult::Ok => Ok((input.slice(index..), input.slice(..index))), 199 _ => { 200 let e: ErrorKind = ErrorKind::Tag; 201 Err(Err::Error(E::from_error_kind(input, e))) 202 } 203 } 204 } else { 205 Ok((input.slice(index..), input.slice(..index))) 206 } 207 } 208 } 209} 210 211/// Recognizes an end of line (both '\n' and '\r\n'). 212/// 213/// *Complete version*: Will return an error if there's not enough input data. 214/// # Example 215/// 216/// ``` 217/// # use nom::{Err, error::{Error, ErrorKind}, IResult, Needed}; 218/// # use nom::character::complete::line_ending; 219/// fn parser(input: &str) -> IResult<&str, &str> { 220/// line_ending(input) 221/// } 222/// 223/// assert_eq!(parser("\r\nc"), Ok(("c", "\r\n"))); 224/// assert_eq!(parser("ab\r\nc"), Err(Err::Error(Error::new("ab\r\nc", ErrorKind::CrLf)))); 225/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::CrLf)))); 226/// ``` 227pub fn line_ending<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> 228where 229 T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>, 230 T: InputIter + InputLength, 231 T: Compare<&'static str>, 232{ 233 match input.compare("\n") { 234 CompareResult::Ok => Ok((input.slice(1..), input.slice(0..1))), 235 CompareResult::Incomplete => Err(Err::Error(E::from_error_kind(input, ErrorKind::CrLf))), 236 CompareResult::Error => { 237 match input.compare("\r\n") { 238 //FIXME: is this the right index? 239 CompareResult::Ok => Ok((input.slice(2..), input.slice(0..2))), 240 _ => Err(Err::Error(E::from_error_kind(input, ErrorKind::CrLf))), 241 } 242 } 243 } 244} 245 246/// Matches a newline character '\n'. 247/// 248/// *Complete version*: Will return an error if there's not enough input data. 249/// # Example 250/// 251/// ``` 252/// # use nom::{Err, error::{Error, ErrorKind}, IResult, Needed}; 253/// # use nom::character::complete::newline; 254/// fn parser(input: &str) -> IResult<&str, char> { 255/// newline(input) 256/// } 257/// 258/// assert_eq!(parser("\nc"), Ok(("c", '\n'))); 259/// assert_eq!(parser("\r\nc"), Err(Err::Error(Error::new("\r\nc", ErrorKind::Char)))); 260/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Char)))); 261/// ``` 262pub fn newline<I, Error: ParseError<I>>(input: I) -> IResult<I, char, Error> 263where 264 I: Slice<RangeFrom<usize>> + InputIter, 265 <I as InputIter>::Item: AsChar, 266{ 267 char('\n')(input) 268} 269 270/// Matches a tab character '\t'. 271/// 272/// *Complete version*: Will return an error if there's not enough input data. 273/// # Example 274/// 275/// ``` 276/// # use nom::{Err, error::{Error, ErrorKind}, IResult, Needed}; 277/// # use nom::character::complete::tab; 278/// fn parser(input: &str) -> IResult<&str, char> { 279/// tab(input) 280/// } 281/// 282/// assert_eq!(parser("\tc"), Ok(("c", '\t'))); 283/// assert_eq!(parser("\r\nc"), Err(Err::Error(Error::new("\r\nc", ErrorKind::Char)))); 284/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Char)))); 285/// ``` 286pub fn tab<I, Error: ParseError<I>>(input: I) -> IResult<I, char, Error> 287where 288 I: Slice<RangeFrom<usize>> + InputIter, 289 <I as InputIter>::Item: AsChar, 290{ 291 char('\t')(input) 292} 293 294/// Matches one byte as a character. Note that the input type will 295/// accept a `str`, but not a `&[u8]`, unlike many other nom parsers. 296/// 297/// *Complete version*: Will return an error if there's not enough input data. 298/// # Example 299/// 300/// ``` 301/// # use nom::{character::complete::anychar, Err, error::{Error, ErrorKind}, IResult}; 302/// fn parser(input: &str) -> IResult<&str, char> { 303/// anychar(input) 304/// } 305/// 306/// assert_eq!(parser("abc"), Ok(("bc",'a'))); 307/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Eof)))); 308/// ``` 309pub fn anychar<T, E: ParseError<T>>(input: T) -> IResult<T, char, E> 310where 311 T: InputIter + InputLength + Slice<RangeFrom<usize>>, 312 <T as InputIter>::Item: AsChar, 313{ 314 let mut it = input.iter_indices(); 315 match it.next() { 316 None => Err(Err::Error(E::from_error_kind(input, ErrorKind::Eof))), 317 Some((_, c)) => match it.next() { 318 None => Ok((input.slice(input.input_len()..), c.as_char())), 319 Some((idx, _)) => Ok((input.slice(idx..), c.as_char())), 320 }, 321 } 322} 323 324/// Recognizes zero or more lowercase and uppercase ASCII alphabetic characters: a-z, A-Z 325/// 326/// *Complete version*: Will return the whole input if no terminating token is found (a non 327/// alphabetic character). 328/// # Example 329/// 330/// ``` 331/// # use nom::{Err, error::ErrorKind, IResult, Needed}; 332/// # use nom::character::complete::alpha0; 333/// fn parser(input: &str) -> IResult<&str, &str> { 334/// alpha0(input) 335/// } 336/// 337/// assert_eq!(parser("ab1c"), Ok(("1c", "ab"))); 338/// assert_eq!(parser("1c"), Ok(("1c", ""))); 339/// assert_eq!(parser(""), Ok(("", ""))); 340/// ``` 341pub fn alpha0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> 342where 343 T: InputTakeAtPosition, 344 <T as InputTakeAtPosition>::Item: AsChar, 345{ 346 input.split_at_position_complete(|item| !item.is_alpha()) 347} 348 349/// Recognizes one or more lowercase and uppercase ASCII alphabetic characters: a-z, A-Z 350/// 351/// *Complete version*: Will return an error if there's not enough input data, 352/// or the whole input if no terminating token is found (a non alphabetic character). 353/// # Example 354/// 355/// ``` 356/// # use nom::{Err, error::{Error, ErrorKind}, IResult, Needed}; 357/// # use nom::character::complete::alpha1; 358/// fn parser(input: &str) -> IResult<&str, &str> { 359/// alpha1(input) 360/// } 361/// 362/// assert_eq!(parser("aB1c"), Ok(("1c", "aB"))); 363/// assert_eq!(parser("1c"), Err(Err::Error(Error::new("1c", ErrorKind::Alpha)))); 364/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Alpha)))); 365/// ``` 366pub fn alpha1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> 367where 368 T: InputTakeAtPosition, 369 <T as InputTakeAtPosition>::Item: AsChar, 370{ 371 input.split_at_position1_complete(|item| !item.is_alpha(), ErrorKind::Alpha) 372} 373 374/// Recognizes zero or more ASCII numerical characters: 0-9 375/// 376/// *Complete version*: Will return an error if there's not enough input data, 377/// or the whole input if no terminating token is found (a non digit character). 378/// # Example 379/// 380/// ``` 381/// # use nom::{Err, error::ErrorKind, IResult, Needed}; 382/// # use nom::character::complete::digit0; 383/// fn parser(input: &str) -> IResult<&str, &str> { 384/// digit0(input) 385/// } 386/// 387/// assert_eq!(parser("21c"), Ok(("c", "21"))); 388/// assert_eq!(parser("21"), Ok(("", "21"))); 389/// assert_eq!(parser("a21c"), Ok(("a21c", ""))); 390/// assert_eq!(parser(""), Ok(("", ""))); 391/// ``` 392pub fn digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> 393where 394 T: InputTakeAtPosition, 395 <T as InputTakeAtPosition>::Item: AsChar, 396{ 397 input.split_at_position_complete(|item| !item.is_dec_digit()) 398} 399 400/// Recognizes one or more ASCII numerical characters: 0-9 401/// 402/// *Complete version*: Will return an error if there's not enough input data, 403/// or the whole input if no terminating token is found (a non digit character). 404/// # Example 405/// 406/// ``` 407/// # use nom::{Err, error::{Error, ErrorKind}, IResult, Needed}; 408/// # use nom::character::complete::digit1; 409/// fn parser(input: &str) -> IResult<&str, &str> { 410/// digit1(input) 411/// } 412/// 413/// assert_eq!(parser("21c"), Ok(("c", "21"))); 414/// assert_eq!(parser("c1"), Err(Err::Error(Error::new("c1", ErrorKind::Digit)))); 415/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Digit)))); 416/// ``` 417/// 418/// ## Parsing an integer 419/// You can use `digit1` in combination with [`map_res`] to parse an integer: 420/// 421/// ``` 422/// # use nom::{Err, error::{Error, ErrorKind}, IResult, Needed}; 423/// # use nom::combinator::map_res; 424/// # use nom::character::complete::digit1; 425/// fn parser(input: &str) -> IResult<&str, u32> { 426/// map_res(digit1, str::parse)(input) 427/// } 428/// 429/// assert_eq!(parser("416"), Ok(("", 416))); 430/// assert_eq!(parser("12b"), Ok(("b", 12))); 431/// assert!(parser("b").is_err()); 432/// ``` 433/// 434/// [`map_res`]: crate::combinator::map_res 435pub fn digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> 436where 437 T: InputTakeAtPosition, 438 <T as InputTakeAtPosition>::Item: AsChar, 439{ 440 input.split_at_position1_complete(|item| !item.is_dec_digit(), ErrorKind::Digit) 441} 442 443/// Recognizes zero or more ASCII hexadecimal numerical characters: 0-9, A-F, a-f 444/// 445/// *Complete version*: Will return the whole input if no terminating token is found (a non hexadecimal digit character). 446/// # Example 447/// 448/// ``` 449/// # use nom::{Err, error::ErrorKind, IResult, Needed}; 450/// # use nom::character::complete::hex_digit0; 451/// fn parser(input: &str) -> IResult<&str, &str> { 452/// hex_digit0(input) 453/// } 454/// 455/// assert_eq!(parser("21cZ"), Ok(("Z", "21c"))); 456/// assert_eq!(parser("Z21c"), Ok(("Z21c", ""))); 457/// assert_eq!(parser(""), Ok(("", ""))); 458/// ``` 459pub fn hex_digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> 460where 461 T: InputTakeAtPosition, 462 <T as InputTakeAtPosition>::Item: AsChar, 463{ 464 input.split_at_position_complete(|item| !item.is_hex_digit()) 465} 466/// Recognizes one or more ASCII hexadecimal numerical characters: 0-9, A-F, a-f 467/// 468/// *Complete version*: Will return an error if there's not enough input data, 469/// or the whole input if no terminating token is found (a non hexadecimal digit character). 470/// # Example 471/// 472/// ``` 473/// # use nom::{Err, error::{Error, ErrorKind}, IResult, Needed}; 474/// # use nom::character::complete::hex_digit1; 475/// fn parser(input: &str) -> IResult<&str, &str> { 476/// hex_digit1(input) 477/// } 478/// 479/// assert_eq!(parser("21cZ"), Ok(("Z", "21c"))); 480/// assert_eq!(parser("H2"), Err(Err::Error(Error::new("H2", ErrorKind::HexDigit)))); 481/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::HexDigit)))); 482/// ``` 483pub fn hex_digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> 484where 485 T: InputTakeAtPosition, 486 <T as InputTakeAtPosition>::Item: AsChar, 487{ 488 input.split_at_position1_complete(|item| !item.is_hex_digit(), ErrorKind::HexDigit) 489} 490 491/// Recognizes zero or more octal characters: 0-7 492/// 493/// *Complete version*: Will return the whole input if no terminating token is found (a non octal 494/// digit character). 495/// # Example 496/// 497/// ``` 498/// # use nom::{Err, error::ErrorKind, IResult, Needed}; 499/// # use nom::character::complete::oct_digit0; 500/// fn parser(input: &str) -> IResult<&str, &str> { 501/// oct_digit0(input) 502/// } 503/// 504/// assert_eq!(parser("21cZ"), Ok(("cZ", "21"))); 505/// assert_eq!(parser("Z21c"), Ok(("Z21c", ""))); 506/// assert_eq!(parser(""), Ok(("", ""))); 507/// ``` 508pub fn oct_digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> 509where 510 T: InputTakeAtPosition, 511 <T as InputTakeAtPosition>::Item: AsChar, 512{ 513 input.split_at_position_complete(|item| !item.is_oct_digit()) 514} 515 516/// Recognizes one or more octal characters: 0-7 517/// 518/// *Complete version*: Will return an error if there's not enough input data, 519/// or the whole input if no terminating token is found (a non octal digit character). 520/// # Example 521/// 522/// ``` 523/// # use nom::{Err, error::{Error, ErrorKind}, IResult, Needed}; 524/// # use nom::character::complete::oct_digit1; 525/// fn parser(input: &str) -> IResult<&str, &str> { 526/// oct_digit1(input) 527/// } 528/// 529/// assert_eq!(parser("21cZ"), Ok(("cZ", "21"))); 530/// assert_eq!(parser("H2"), Err(Err::Error(Error::new("H2", ErrorKind::OctDigit)))); 531/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::OctDigit)))); 532/// ``` 533pub fn oct_digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> 534where 535 T: InputTakeAtPosition, 536 <T as InputTakeAtPosition>::Item: AsChar, 537{ 538 input.split_at_position1_complete(|item| !item.is_oct_digit(), ErrorKind::OctDigit) 539} 540 541/// Recognizes zero or more ASCII numerical and alphabetic characters: 0-9, a-z, A-Z 542/// 543/// *Complete version*: Will return the whole input if no terminating token is found (a non 544/// alphanumerical character). 545/// # Example 546/// 547/// ``` 548/// # use nom::{Err, error::ErrorKind, IResult, Needed}; 549/// # use nom::character::complete::alphanumeric0; 550/// fn parser(input: &str) -> IResult<&str, &str> { 551/// alphanumeric0(input) 552/// } 553/// 554/// assert_eq!(parser("21cZ%1"), Ok(("%1", "21cZ"))); 555/// assert_eq!(parser("&Z21c"), Ok(("&Z21c", ""))); 556/// assert_eq!(parser(""), Ok(("", ""))); 557/// ``` 558pub fn alphanumeric0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> 559where 560 T: InputTakeAtPosition, 561 <T as InputTakeAtPosition>::Item: AsChar, 562{ 563 input.split_at_position_complete(|item| !item.is_alphanum()) 564} 565 566/// Recognizes one or more ASCII numerical and alphabetic characters: 0-9, a-z, A-Z 567/// 568/// *Complete version*: Will return an error if there's not enough input data, 569/// or the whole input if no terminating token is found (a non alphanumerical character). 570/// # Example 571/// 572/// ``` 573/// # use nom::{Err, error::{Error, ErrorKind}, IResult, Needed}; 574/// # use nom::character::complete::alphanumeric1; 575/// fn parser(input: &str) -> IResult<&str, &str> { 576/// alphanumeric1(input) 577/// } 578/// 579/// assert_eq!(parser("21cZ%1"), Ok(("%1", "21cZ"))); 580/// assert_eq!(parser("&H2"), Err(Err::Error(Error::new("&H2", ErrorKind::AlphaNumeric)))); 581/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::AlphaNumeric)))); 582/// ``` 583pub fn alphanumeric1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> 584where 585 T: InputTakeAtPosition, 586 <T as InputTakeAtPosition>::Item: AsChar, 587{ 588 input.split_at_position1_complete(|item| !item.is_alphanum(), ErrorKind::AlphaNumeric) 589} 590 591/// Recognizes zero or more spaces and tabs. 592/// 593/// *Complete version*: Will return the whole input if no terminating token is found (a non space 594/// character). 595/// # Example 596/// 597/// ``` 598/// # use nom::{Err, error::ErrorKind, IResult, Needed}; 599/// # use nom::character::complete::space0; 600/// fn parser(input: &str) -> IResult<&str, &str> { 601/// space0(input) 602/// } 603/// 604/// assert_eq!(parser(" \t21c"), Ok(("21c", " \t"))); 605/// assert_eq!(parser("Z21c"), Ok(("Z21c", ""))); 606/// assert_eq!(parser(""), Ok(("", ""))); 607/// ``` 608pub fn space0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> 609where 610 T: InputTakeAtPosition, 611 <T as InputTakeAtPosition>::Item: AsChar + Clone, 612{ 613 input.split_at_position_complete(|item| { 614 let c = item.as_char(); 615 !(c == ' ' || c == '\t') 616 }) 617} 618 619/// Recognizes one or more spaces and tabs. 620/// 621/// *Complete version*: Will return an error if there's not enough input data, 622/// or the whole input if no terminating token is found (a non space character). 623/// # Example 624/// 625/// ``` 626/// # use nom::{Err, error::{Error, ErrorKind}, IResult, Needed}; 627/// # use nom::character::complete::space1; 628/// fn parser(input: &str) -> IResult<&str, &str> { 629/// space1(input) 630/// } 631/// 632/// assert_eq!(parser(" \t21c"), Ok(("21c", " \t"))); 633/// assert_eq!(parser("H2"), Err(Err::Error(Error::new("H2", ErrorKind::Space)))); 634/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Space)))); 635/// ``` 636pub fn space1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> 637where 638 T: InputTakeAtPosition, 639 <T as InputTakeAtPosition>::Item: AsChar + Clone, 640{ 641 input.split_at_position1_complete( 642 |item| { 643 let c = item.as_char(); 644 !(c == ' ' || c == '\t') 645 }, 646 ErrorKind::Space, 647 ) 648} 649 650/// Recognizes zero or more spaces, tabs, carriage returns and line feeds. 651/// 652/// *Complete version*: will return the whole input if no terminating token is found (a non space 653/// character). 654/// # Example 655/// 656/// ``` 657/// # use nom::{Err, error::ErrorKind, IResult, Needed}; 658/// # use nom::character::complete::multispace0; 659/// fn parser(input: &str) -> IResult<&str, &str> { 660/// multispace0(input) 661/// } 662/// 663/// assert_eq!(parser(" \t\n\r21c"), Ok(("21c", " \t\n\r"))); 664/// assert_eq!(parser("Z21c"), Ok(("Z21c", ""))); 665/// assert_eq!(parser(""), Ok(("", ""))); 666/// ``` 667pub fn multispace0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> 668where 669 T: InputTakeAtPosition, 670 <T as InputTakeAtPosition>::Item: AsChar + Clone, 671{ 672 input.split_at_position_complete(|item| { 673 let c = item.as_char(); 674 !(c == ' ' || c == '\t' || c == '\r' || c == '\n') 675 }) 676} 677 678/// Recognizes one or more spaces, tabs, carriage returns and line feeds. 679/// 680/// *Complete version*: will return an error if there's not enough input data, 681/// or the whole input if no terminating token is found (a non space character). 682/// # Example 683/// 684/// ``` 685/// # use nom::{Err, error::{Error, ErrorKind}, IResult, Needed}; 686/// # use nom::character::complete::multispace1; 687/// fn parser(input: &str) -> IResult<&str, &str> { 688/// multispace1(input) 689/// } 690/// 691/// assert_eq!(parser(" \t\n\r21c"), Ok(("21c", " \t\n\r"))); 692/// assert_eq!(parser("H2"), Err(Err::Error(Error::new("H2", ErrorKind::MultiSpace)))); 693/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::MultiSpace)))); 694/// ``` 695pub fn multispace1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> 696where 697 T: InputTakeAtPosition, 698 <T as InputTakeAtPosition>::Item: AsChar + Clone, 699{ 700 input.split_at_position1_complete( 701 |item| { 702 let c = item.as_char(); 703 !(c == ' ' || c == '\t' || c == '\r' || c == '\n') 704 }, 705 ErrorKind::MultiSpace, 706 ) 707} 708 709pub(crate) fn sign<T, E: ParseError<T>>(input: T) -> IResult<T, bool, E> 710where 711 T: Clone + InputTake, 712 T: for<'a> Compare<&'a [u8]>, 713{ 714 use crate::bytes::complete::tag; 715 use crate::combinator::value; 716 717 let (i, opt_sign) = opt(alt(( 718 value(false, tag(&b"-"[..])), 719 value(true, tag(&b"+"[..])), 720 )))(input)?; 721 let sign = opt_sign.unwrap_or(true); 722 723 Ok((i, sign)) 724} 725 726#[doc(hidden)] 727macro_rules! ints { 728 ($($t:tt)+) => { 729 $( 730 /// will parse a number in text form to a number 731 /// 732 /// *Complete version*: can parse until the end of input. 733 pub fn $t<T, E: ParseError<T>>(input: T) -> IResult<T, $t, E> 734 where 735 T: InputIter + Slice<RangeFrom<usize>> + InputLength + InputTake + Clone, 736 <T as InputIter>::Item: AsChar, 737 T: for <'a> Compare<&'a[u8]>, 738 { 739 let (i, sign) = sign(input.clone())?; 740 741 if i.input_len() == 0 { 742 return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit))); 743 } 744 745 let mut value: $t = 0; 746 if sign { 747 for (pos, c) in i.iter_indices() { 748 match c.as_char().to_digit(10) { 749 None => { 750 if pos == 0 { 751 return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit))); 752 } else { 753 return Ok((i.slice(pos..), value)); 754 } 755 }, 756 Some(d) => match value.checked_mul(10).and_then(|v| v.checked_add(d as $t)) { 757 None => return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit))), 758 Some(v) => value = v, 759 } 760 } 761 } 762 } else { 763 for (pos, c) in i.iter_indices() { 764 match c.as_char().to_digit(10) { 765 None => { 766 if pos == 0 { 767 return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit))); 768 } else { 769 return Ok((i.slice(pos..), value)); 770 } 771 }, 772 Some(d) => match value.checked_mul(10).and_then(|v| v.checked_sub(d as $t)) { 773 None => return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit))), 774 Some(v) => value = v, 775 } 776 } 777 } 778 } 779 780 Ok((i.slice(i.input_len()..), value)) 781 } 782 )+ 783 } 784} 785 786ints! { i8 i16 i32 i64 i128 } 787 788#[doc(hidden)] 789macro_rules! uints { 790 ($($t:tt)+) => { 791 $( 792 /// will parse a number in text form to a number 793 /// 794 /// *Complete version*: can parse until the end of input. 795 pub fn $t<T, E: ParseError<T>>(input: T) -> IResult<T, $t, E> 796 where 797 T: InputIter + Slice<RangeFrom<usize>> + InputLength, 798 <T as InputIter>::Item: AsChar, 799 { 800 let i = input; 801 802 if i.input_len() == 0 { 803 return Err(Err::Error(E::from_error_kind(i, ErrorKind::Digit))); 804 } 805 806 let mut value: $t = 0; 807 for (pos, c) in i.iter_indices() { 808 match c.as_char().to_digit(10) { 809 None => { 810 if pos == 0 { 811 return Err(Err::Error(E::from_error_kind(i, ErrorKind::Digit))); 812 } else { 813 return Ok((i.slice(pos..), value)); 814 } 815 }, 816 Some(d) => match value.checked_mul(10).and_then(|v| v.checked_add(d as $t)) { 817 None => return Err(Err::Error(E::from_error_kind(i, ErrorKind::Digit))), 818 Some(v) => value = v, 819 } 820 } 821 } 822 823 Ok((i.slice(i.input_len()..), value)) 824 } 825 )+ 826 } 827} 828 829uints! { u8 u16 u32 u64 u128 } 830 831#[cfg(test)] 832mod tests { 833 use super::*; 834 use crate::internal::Err; 835 use crate::traits::ParseTo; 836 use proptest::prelude::*; 837 838 macro_rules! assert_parse( 839 ($left: expr, $right: expr) => { 840 let res: $crate::IResult<_, _, (_, ErrorKind)> = $left; 841 assert_eq!(res, $right); 842 }; 843 ); 844 845 #[test] 846 fn character() { 847 let empty: &[u8] = b""; 848 let a: &[u8] = b"abcd"; 849 let b: &[u8] = b"1234"; 850 let c: &[u8] = b"a123"; 851 let d: &[u8] = "azé12".as_bytes(); 852 let e: &[u8] = b" "; 853 let f: &[u8] = b" ;"; 854 //assert_eq!(alpha1::<_, (_, ErrorKind)>(a), Err(Err::Incomplete(Needed::Size(1)))); 855 assert_parse!(alpha1(a), Ok((empty, a))); 856 assert_eq!(alpha1(b), Err(Err::Error((b, ErrorKind::Alpha)))); 857 assert_eq!(alpha1::<_, (_, ErrorKind)>(c), Ok((&c[1..], &b"a"[..]))); 858 assert_eq!( 859 alpha1::<_, (_, ErrorKind)>(d), 860 Ok(("é12".as_bytes(), &b"az"[..])) 861 ); 862 assert_eq!(digit1(a), Err(Err::Error((a, ErrorKind::Digit)))); 863 assert_eq!(digit1::<_, (_, ErrorKind)>(b), Ok((empty, b))); 864 assert_eq!(digit1(c), Err(Err::Error((c, ErrorKind::Digit)))); 865 assert_eq!(digit1(d), Err(Err::Error((d, ErrorKind::Digit)))); 866 assert_eq!(hex_digit1::<_, (_, ErrorKind)>(a), Ok((empty, a))); 867 assert_eq!(hex_digit1::<_, (_, ErrorKind)>(b), Ok((empty, b))); 868 assert_eq!(hex_digit1::<_, (_, ErrorKind)>(c), Ok((empty, c))); 869 assert_eq!( 870 hex_digit1::<_, (_, ErrorKind)>(d), 871 Ok(("zé12".as_bytes(), &b"a"[..])) 872 ); 873 assert_eq!(hex_digit1(e), Err(Err::Error((e, ErrorKind::HexDigit)))); 874 assert_eq!(oct_digit1(a), Err(Err::Error((a, ErrorKind::OctDigit)))); 875 assert_eq!(oct_digit1::<_, (_, ErrorKind)>(b), Ok((empty, b))); 876 assert_eq!(oct_digit1(c), Err(Err::Error((c, ErrorKind::OctDigit)))); 877 assert_eq!(oct_digit1(d), Err(Err::Error((d, ErrorKind::OctDigit)))); 878 assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(a), Ok((empty, a))); 879 //assert_eq!(fix_error!(b,(), alphanumeric), Ok((empty, b))); 880 assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(c), Ok((empty, c))); 881 assert_eq!( 882 alphanumeric1::<_, (_, ErrorKind)>(d), 883 Ok(("é12".as_bytes(), &b"az"[..])) 884 ); 885 assert_eq!(space1::<_, (_, ErrorKind)>(e), Ok((empty, e))); 886 assert_eq!(space1::<_, (_, ErrorKind)>(f), Ok((&b";"[..], &b" "[..]))); 887 } 888 889 #[cfg(feature = "alloc")] 890 #[test] 891 fn character_s() { 892 let empty = ""; 893 let a = "abcd"; 894 let b = "1234"; 895 let c = "a123"; 896 let d = "azé12"; 897 let e = " "; 898 assert_eq!(alpha1::<_, (_, ErrorKind)>(a), Ok((empty, a))); 899 assert_eq!(alpha1(b), Err(Err::Error((b, ErrorKind::Alpha)))); 900 assert_eq!(alpha1::<_, (_, ErrorKind)>(c), Ok((&c[1..], &"a"[..]))); 901 assert_eq!(alpha1::<_, (_, ErrorKind)>(d), Ok(("é12", &"az"[..]))); 902 assert_eq!(digit1(a), Err(Err::Error((a, ErrorKind::Digit)))); 903 assert_eq!(digit1::<_, (_, ErrorKind)>(b), Ok((empty, b))); 904 assert_eq!(digit1(c), Err(Err::Error((c, ErrorKind::Digit)))); 905 assert_eq!(digit1(d), Err(Err::Error((d, ErrorKind::Digit)))); 906 assert_eq!(hex_digit1::<_, (_, ErrorKind)>(a), Ok((empty, a))); 907 assert_eq!(hex_digit1::<_, (_, ErrorKind)>(b), Ok((empty, b))); 908 assert_eq!(hex_digit1::<_, (_, ErrorKind)>(c), Ok((empty, c))); 909 assert_eq!(hex_digit1::<_, (_, ErrorKind)>(d), Ok(("zé12", &"a"[..]))); 910 assert_eq!(hex_digit1(e), Err(Err::Error((e, ErrorKind::HexDigit)))); 911 assert_eq!(oct_digit1(a), Err(Err::Error((a, ErrorKind::OctDigit)))); 912 assert_eq!(oct_digit1::<_, (_, ErrorKind)>(b), Ok((empty, b))); 913 assert_eq!(oct_digit1(c), Err(Err::Error((c, ErrorKind::OctDigit)))); 914 assert_eq!(oct_digit1(d), Err(Err::Error((d, ErrorKind::OctDigit)))); 915 assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(a), Ok((empty, a))); 916 //assert_eq!(fix_error!(b,(), alphanumeric), Ok((empty, b))); 917 assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(c), Ok((empty, c))); 918 assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(d), Ok(("é12", "az"))); 919 assert_eq!(space1::<_, (_, ErrorKind)>(e), Ok((empty, e))); 920 } 921 922 use crate::traits::Offset; 923 #[test] 924 fn offset() { 925 let a = &b"abcd;"[..]; 926 let b = &b"1234;"[..]; 927 let c = &b"a123;"[..]; 928 let d = &b" \t;"[..]; 929 let e = &b" \t\r\n;"[..]; 930 let f = &b"123abcDEF;"[..]; 931 932 match alpha1::<_, (_, ErrorKind)>(a) { 933 Ok((i, _)) => { 934 assert_eq!(a.offset(i) + i.len(), a.len()); 935 } 936 _ => panic!("wrong return type in offset test for alpha"), 937 } 938 match digit1::<_, (_, ErrorKind)>(b) { 939 Ok((i, _)) => { 940 assert_eq!(b.offset(i) + i.len(), b.len()); 941 } 942 _ => panic!("wrong return type in offset test for digit"), 943 } 944 match alphanumeric1::<_, (_, ErrorKind)>(c) { 945 Ok((i, _)) => { 946 assert_eq!(c.offset(i) + i.len(), c.len()); 947 } 948 _ => panic!("wrong return type in offset test for alphanumeric"), 949 } 950 match space1::<_, (_, ErrorKind)>(d) { 951 Ok((i, _)) => { 952 assert_eq!(d.offset(i) + i.len(), d.len()); 953 } 954 _ => panic!("wrong return type in offset test for space"), 955 } 956 match multispace1::<_, (_, ErrorKind)>(e) { 957 Ok((i, _)) => { 958 assert_eq!(e.offset(i) + i.len(), e.len()); 959 } 960 _ => panic!("wrong return type in offset test for multispace"), 961 } 962 match hex_digit1::<_, (_, ErrorKind)>(f) { 963 Ok((i, _)) => { 964 assert_eq!(f.offset(i) + i.len(), f.len()); 965 } 966 _ => panic!("wrong return type in offset test for hex_digit"), 967 } 968 match oct_digit1::<_, (_, ErrorKind)>(f) { 969 Ok((i, _)) => { 970 assert_eq!(f.offset(i) + i.len(), f.len()); 971 } 972 _ => panic!("wrong return type in offset test for oct_digit"), 973 } 974 } 975 976 #[test] 977 fn is_not_line_ending_bytes() { 978 let a: &[u8] = b"ab12cd\nefgh"; 979 assert_eq!( 980 not_line_ending::<_, (_, ErrorKind)>(a), 981 Ok((&b"\nefgh"[..], &b"ab12cd"[..])) 982 ); 983 984 let b: &[u8] = b"ab12cd\nefgh\nijkl"; 985 assert_eq!( 986 not_line_ending::<_, (_, ErrorKind)>(b), 987 Ok((&b"\nefgh\nijkl"[..], &b"ab12cd"[..])) 988 ); 989 990 let c: &[u8] = b"ab12cd\r\nefgh\nijkl"; 991 assert_eq!( 992 not_line_ending::<_, (_, ErrorKind)>(c), 993 Ok((&b"\r\nefgh\nijkl"[..], &b"ab12cd"[..])) 994 ); 995 996 let d: &[u8] = b"ab12cd"; 997 assert_eq!( 998 not_line_ending::<_, (_, ErrorKind)>(d), 999 Ok((&[][..], &d[..])) 1000 ); 1001 } 1002 1003 #[test] 1004 fn is_not_line_ending_str() { 1005 /* 1006 let a: &str = "ab12cd\nefgh"; 1007 assert_eq!(not_line_ending(a), Ok((&"\nefgh"[..], &"ab12cd"[..]))); 1008 1009 let b: &str = "ab12cd\nefgh\nijkl"; 1010 assert_eq!(not_line_ending(b), Ok((&"\nefgh\nijkl"[..], &"ab12cd"[..]))); 1011 1012 let c: &str = "ab12cd\r\nefgh\nijkl"; 1013 assert_eq!(not_line_ending(c), Ok((&"\r\nefgh\nijkl"[..], &"ab12cd"[..]))); 1014 1015 let d = "βèƒôřè\nÂßÇáƒƭèř"; 1016 assert_eq!(not_line_ending(d), Ok((&"\nÂßÇáƒƭèř"[..], &"βèƒôřè"[..]))); 1017 1018 let e = "βèƒôřè\r\nÂßÇáƒƭèř"; 1019 assert_eq!(not_line_ending(e), Ok((&"\r\nÂßÇáƒƭèř"[..], &"βèƒôřè"[..]))); 1020 */ 1021 1022 let f = "βèƒôřè\rÂßÇáƒƭèř"; 1023 assert_eq!(not_line_ending(f), Err(Err::Error((f, ErrorKind::Tag)))); 1024 1025 let g2: &str = "ab12cd"; 1026 assert_eq!(not_line_ending::<_, (_, ErrorKind)>(g2), Ok(("", g2))); 1027 } 1028 1029 #[test] 1030 fn hex_digit_test() { 1031 let i = &b"0123456789abcdefABCDEF;"[..]; 1032 assert_parse!(hex_digit1(i), Ok((&b";"[..], &i[..i.len() - 1]))); 1033 1034 let i = &b"g"[..]; 1035 assert_parse!( 1036 hex_digit1(i), 1037 Err(Err::Error(error_position!(i, ErrorKind::HexDigit))) 1038 ); 1039 1040 let i = &b"G"[..]; 1041 assert_parse!( 1042 hex_digit1(i), 1043 Err(Err::Error(error_position!(i, ErrorKind::HexDigit))) 1044 ); 1045 1046 assert!(crate::character::is_hex_digit(b'0')); 1047 assert!(crate::character::is_hex_digit(b'9')); 1048 assert!(crate::character::is_hex_digit(b'a')); 1049 assert!(crate::character::is_hex_digit(b'f')); 1050 assert!(crate::character::is_hex_digit(b'A')); 1051 assert!(crate::character::is_hex_digit(b'F')); 1052 assert!(!crate::character::is_hex_digit(b'g')); 1053 assert!(!crate::character::is_hex_digit(b'G')); 1054 assert!(!crate::character::is_hex_digit(b'/')); 1055 assert!(!crate::character::is_hex_digit(b':')); 1056 assert!(!crate::character::is_hex_digit(b'@')); 1057 assert!(!crate::character::is_hex_digit(b'\x60')); 1058 } 1059 1060 #[test] 1061 fn oct_digit_test() { 1062 let i = &b"01234567;"[..]; 1063 assert_parse!(oct_digit1(i), Ok((&b";"[..], &i[..i.len() - 1]))); 1064 1065 let i = &b"8"[..]; 1066 assert_parse!( 1067 oct_digit1(i), 1068 Err(Err::Error(error_position!(i, ErrorKind::OctDigit))) 1069 ); 1070 1071 assert!(crate::character::is_oct_digit(b'0')); 1072 assert!(crate::character::is_oct_digit(b'7')); 1073 assert!(!crate::character::is_oct_digit(b'8')); 1074 assert!(!crate::character::is_oct_digit(b'9')); 1075 assert!(!crate::character::is_oct_digit(b'a')); 1076 assert!(!crate::character::is_oct_digit(b'A')); 1077 assert!(!crate::character::is_oct_digit(b'/')); 1078 assert!(!crate::character::is_oct_digit(b':')); 1079 assert!(!crate::character::is_oct_digit(b'@')); 1080 assert!(!crate::character::is_oct_digit(b'\x60')); 1081 } 1082 1083 #[test] 1084 fn full_line_windows() { 1085 use crate::sequence::pair; 1086 fn take_full_line(i: &[u8]) -> IResult<&[u8], (&[u8], &[u8])> { 1087 pair(not_line_ending, line_ending)(i) 1088 } 1089 let input = b"abc\r\n"; 1090 let output = take_full_line(input); 1091 assert_eq!(output, Ok((&b""[..], (&b"abc"[..], &b"\r\n"[..])))); 1092 } 1093 1094 #[test] 1095 fn full_line_unix() { 1096 use crate::sequence::pair; 1097 fn take_full_line(i: &[u8]) -> IResult<&[u8], (&[u8], &[u8])> { 1098 pair(not_line_ending, line_ending)(i) 1099 } 1100 let input = b"abc\n"; 1101 let output = take_full_line(input); 1102 assert_eq!(output, Ok((&b""[..], (&b"abc"[..], &b"\n"[..])))); 1103 } 1104 1105 #[test] 1106 fn check_windows_lineending() { 1107 let input = b"\r\n"; 1108 let output = line_ending(&input[..]); 1109 assert_parse!(output, Ok((&b""[..], &b"\r\n"[..]))); 1110 } 1111 1112 #[test] 1113 fn check_unix_lineending() { 1114 let input = b"\n"; 1115 let output = line_ending(&input[..]); 1116 assert_parse!(output, Ok((&b""[..], &b"\n"[..]))); 1117 } 1118 1119 #[test] 1120 fn cr_lf() { 1121 assert_parse!(crlf(&b"\r\na"[..]), Ok((&b"a"[..], &b"\r\n"[..]))); 1122 assert_parse!( 1123 crlf(&b"\r"[..]), 1124 Err(Err::Error(error_position!(&b"\r"[..], ErrorKind::CrLf))) 1125 ); 1126 assert_parse!( 1127 crlf(&b"\ra"[..]), 1128 Err(Err::Error(error_position!(&b"\ra"[..], ErrorKind::CrLf))) 1129 ); 1130 1131 assert_parse!(crlf("\r\na"), Ok(("a", "\r\n"))); 1132 assert_parse!( 1133 crlf("\r"), 1134 Err(Err::Error(error_position!(&"\r"[..], ErrorKind::CrLf))) 1135 ); 1136 assert_parse!( 1137 crlf("\ra"), 1138 Err(Err::Error(error_position!("\ra", ErrorKind::CrLf))) 1139 ); 1140 } 1141 1142 #[test] 1143 fn end_of_line() { 1144 assert_parse!(line_ending(&b"\na"[..]), Ok((&b"a"[..], &b"\n"[..]))); 1145 assert_parse!(line_ending(&b"\r\na"[..]), Ok((&b"a"[..], &b"\r\n"[..]))); 1146 assert_parse!( 1147 line_ending(&b"\r"[..]), 1148 Err(Err::Error(error_position!(&b"\r"[..], ErrorKind::CrLf))) 1149 ); 1150 assert_parse!( 1151 line_ending(&b"\ra"[..]), 1152 Err(Err::Error(error_position!(&b"\ra"[..], ErrorKind::CrLf))) 1153 ); 1154 1155 assert_parse!(line_ending("\na"), Ok(("a", "\n"))); 1156 assert_parse!(line_ending("\r\na"), Ok(("a", "\r\n"))); 1157 assert_parse!( 1158 line_ending("\r"), 1159 Err(Err::Error(error_position!(&"\r"[..], ErrorKind::CrLf))) 1160 ); 1161 assert_parse!( 1162 line_ending("\ra"), 1163 Err(Err::Error(error_position!("\ra", ErrorKind::CrLf))) 1164 ); 1165 } 1166 1167 fn digit_to_i16(input: &str) -> IResult<&str, i16> { 1168 let i = input; 1169 let (i, opt_sign) = opt(alt((char('+'), char('-'))))(i)?; 1170 let sign = match opt_sign { 1171 Some('+') => true, 1172 Some('-') => false, 1173 _ => true, 1174 }; 1175 1176 let (i, s) = match digit1::<_, crate::error::Error<_>>(i) { 1177 Ok((i, s)) => (i, s), 1178 Err(_) => { 1179 return Err(Err::Error(crate::error::Error::from_error_kind( 1180 input, 1181 ErrorKind::Digit, 1182 ))) 1183 } 1184 }; 1185 1186 match s.parse_to() { 1187 Some(n) => { 1188 if sign { 1189 Ok((i, n)) 1190 } else { 1191 Ok((i, -n)) 1192 } 1193 } 1194 None => Err(Err::Error(crate::error::Error::from_error_kind( 1195 i, 1196 ErrorKind::Digit, 1197 ))), 1198 } 1199 } 1200 1201 fn digit_to_u32(i: &str) -> IResult<&str, u32> { 1202 let (i, s) = digit1(i)?; 1203 match s.parse_to() { 1204 Some(n) => Ok((i, n)), 1205 None => Err(Err::Error(crate::error::Error::from_error_kind( 1206 i, 1207 ErrorKind::Digit, 1208 ))), 1209 } 1210 } 1211 1212 proptest! { 1213 #[test] 1214 fn ints(s in "\\PC*") { 1215 let res1 = digit_to_i16(&s); 1216 let res2 = i16(s.as_str()); 1217 assert_eq!(res1, res2); 1218 } 1219 1220 #[test] 1221 fn uints(s in "\\PC*") { 1222 let res1 = digit_to_u32(&s); 1223 let res2 = u32(s.as_str()); 1224 assert_eq!(res1, res2); 1225 } 1226 } 1227} 1228