mod macros;
pub mod str {
use crate::error::{ErrorKind, ParseError};
use crate::lib::regex::Regex;
#[cfg(feature = "alloc")]
use crate::lib::std::vec::Vec;
use crate::traits::{InputLength, Slice};
use crate::{Err, IResult};
#[cfg(feature = "regexp")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "regexp")))]
pub fn re_match<'a, E>(re: Regex) -> impl Fn(&'a str) -> IResult<&'a str, &'a str, E>
where
E: ParseError<&'a str>,
{
move |i| {
if re.is_match(i) {
Ok((i.slice(i.input_len()..), i))
} else {
Err(Err::Error(E::from_error_kind(i, ErrorKind::RegexpMatch)))
}
}
}
#[cfg(all(feature = "regexp", feature = "alloc"))]
#[cfg_attr(
feature = "docsrs",
doc(cfg(all(feature = "regexp", feature = "alloc")))
)]
pub fn re_matches<'a, E>(re: Regex) -> impl Fn(&'a str) -> IResult<&'a str, Vec<&'a str>, E>
where
E: ParseError<&'a str>,
{
move |i| {
let v: Vec<_> = re
.find_iter(i)
.map(|m| i.slice(m.start()..m.end()))
.collect();
if !v.is_empty() {
let offset = {
let end = v.last().unwrap();
end.as_ptr() as usize + end.len() - i.as_ptr() as usize
};
Ok((i.slice(offset..), v))
} else {
Err(Err::Error(E::from_error_kind(i, ErrorKind::RegexpMatches)))
}
}
}
#[cfg(feature = "regexp")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "regexp")))]
pub fn re_find<'a, E>(re: Regex) -> impl Fn(&'a str) -> IResult<&'a str, &'a str, E>
where
E: ParseError<&'a str>,
{
move |i| {
if let Some(m) = re.find(i) {
Ok((i.slice(m.end()..), i.slice(m.start()..m.end())))
} else {
Err(Err::Error(E::from_error_kind(i, ErrorKind::RegexpFind)))
}
}
}
#[cfg(all(feature = "regexp", feature = "alloc"))]
#[cfg_attr(
feature = "docsrs",
doc(cfg(all(feature = "regexp", feature = "alloc")))
)]
pub fn re_capture<'a, E>(re: Regex) -> impl Fn(&'a str) -> IResult<&'a str, Vec<&'a str>, E>
where
E: ParseError<&'a str>,
{
move |i| {
if let Some(c) = re.captures(i) {
let v: Vec<_> = c
.iter()
.filter(|el| el.is_some())
.map(|el| el.unwrap())
.map(|m| i.slice(m.start()..m.end()))
.collect();
let offset = {
let end = v.last().unwrap();
end.as_ptr() as usize + end.len() - i.as_ptr() as usize
};
Ok((i.slice(offset..), v))
} else {
Err(Err::Error(E::from_error_kind(i, ErrorKind::RegexpCapture)))
}
}
}
#[cfg(all(feature = "regexp", feature = "alloc"))]
#[cfg_attr(
feature = "docsrs",
doc(cfg(all(feature = "regexp", feature = "alloc")))
)]
pub fn re_captures<'a, E>(re: Regex) -> impl Fn(&'a str) -> IResult<&'a str, Vec<Vec<&'a str>>, E>
where
E: ParseError<&'a str>,
{
move |i| {
let v: Vec<Vec<_>> = re
.captures_iter(i)
.map(|c| {
c.iter()
.filter(|el| el.is_some())
.map(|el| el.unwrap())
.map(|m| i.slice(m.start()..m.end()))
.collect()
})
.collect();
if !v.is_empty() {
let offset = {
let end = v.last().unwrap().last().unwrap();
end.as_ptr() as usize + end.len() - i.as_ptr() as usize
};
Ok((i.slice(offset..), v))
} else {
Err(Err::Error(E::from_error_kind(i, ErrorKind::RegexpCapture)))
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::error::ErrorKind;
use crate::internal::Err;
use crate::lib::regex::Regex;
macro_rules! assert_parse(
($left: expr, $right: expr) => {
let res: $crate::IResult<_, _, (_, ErrorKind)> = $left;
assert_eq!(res, $right);
};
);
#[test]
fn re_match_str() {
let re = Regex::new(r"^\d{4}-\d{2}-\d{2}").unwrap();
let rm = re_match(re);
assert_parse!(rm("2015-09-07"), Ok(("", "2015-09-07")));
assert_eq!(
rm("blah"),
Err(Err::Error((&"blah"[..], ErrorKind::RegexpMatch)))
);
assert_eq!(rm("2015-09-07blah"), Ok(("", "2015-09-07blah")));
}
#[test]
fn re_find_str() {
let re = Regex::new(r"^\d{4}-\d{2}-\d{2}").unwrap();
let rm = re_find(re);
assert_parse!(rm("2015-09-07"), Ok(("", "2015-09-07")));
assert_eq!(
rm("blah"),
Err(Err::Error((&"blah"[..], ErrorKind::RegexpFind)))
);
assert_eq!(rm("2015-09-07blah"), Ok(("blah", "2015-09-07")));
}
#[cfg(feature = "alloc")]
#[test]
fn re_matches_str() {
let re = Regex::new(r"\d{4}-\d{2}-\d{2}").unwrap();
let rm = re_matches(re);
assert_parse!(rm("2015-09-07"), Ok(("", vec!["2015-09-07"])));
assert_eq!(
rm("blah"),
Err(Err::Error((&"blah"[..], ErrorKind::RegexpMatches)))
);
assert_eq!(
rm("aaa2015-09-07blah2015-09-09pouet"),
Ok(("pouet", vec!["2015-09-07", "2015-09-09"]))
);
}
#[cfg(feature = "alloc")]
#[test]
fn re_capture_str() {
let re = Regex::new(r"([[:alpha:]]+)\s+((\d+).(\d+).(\d+))").unwrap();
let rm = re_capture(re);
assert_parse!(
rm("blah nom 0.3.11pouet"),
Ok(("pouet", vec!["nom 0.3.11", "nom", "0.3.11", "0", "3", "11"]))
);
assert_eq!(
rm("blah"),
Err(Err::Error(("blah", ErrorKind::RegexpCapture)))
);
assert_eq!(
rm("hello nom 0.3.11 world regex 0.1.41"),
Ok((
" world regex 0.1.41",
vec!["nom 0.3.11", "nom", "0.3.11", "0", "3", "11"]
))
);
}
#[cfg(feature = "alloc")]
#[test]
fn re_captures_str() {
let re = Regex::new(r"([[:alpha:]]+)\s+((\d+).(\d+).(\d+))").unwrap();
let rm = re_captures(re);
assert_parse!(
rm("blah nom 0.3.11pouet"),
Ok((
"pouet",
vec![vec!["nom 0.3.11", "nom", "0.3.11", "0", "3", "11"]]
))
);
assert_eq!(
rm("blah"),
Err(Err::Error((&"blah"[..], ErrorKind::RegexpCapture)))
);
assert_eq!(
rm("hello nom 0.3.11 world regex 0.1.41 aaa"),
Ok((
" aaa",
vec![
vec!["nom 0.3.11", "nom", "0.3.11", "0", "3", "11"],
vec!["regex 0.1.41", "regex", "0.1.41", "0", "1", "41"],
]
))
);
}
}
}
pub mod bytes {
use crate::error::{ErrorKind, ParseError};
use crate::lib::regex::bytes::Regex;
#[cfg(feature = "alloc")]
use crate::lib::std::vec::Vec;
use crate::traits::{InputLength, Slice};
use crate::{Err, IResult};
#[cfg(feature = "regexp")]
pub fn re_match<'a, E>(re: Regex) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], &'a [u8], E>
where
E: ParseError<&'a [u8]>,
{
move |i| {
if re.is_match(i) {
Ok((i.slice(i.input_len()..), i))
} else {
Err(Err::Error(E::from_error_kind(i, ErrorKind::RegexpMatch)))
}
}
}
#[cfg(all(feature = "regexp", feature = "alloc"))]
#[cfg_attr(
feature = "docsrs",
doc(cfg(all(feature = "regexp", feature = "alloc")))
)]
pub fn re_matches<'a, E>(re: Regex) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], Vec<&'a [u8]>, E>
where
E: ParseError<&'a [u8]>,
{
move |i| {
let v: Vec<_> = re
.find_iter(i)
.map(|m| i.slice(m.start()..m.end()))
.collect();
if !v.is_empty() {
let offset = {
let end = v.last().unwrap();
end.as_ptr() as usize + end.len() - i.as_ptr() as usize
};
Ok((i.slice(offset..), v))
} else {
Err(Err::Error(E::from_error_kind(i, ErrorKind::RegexpMatches)))
}
}
}
#[cfg(feature = "regexp")]
pub fn re_find<'a, E>(re: Regex) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], &'a [u8], E>
where
E: ParseError<&'a [u8]>,
{
move |i| {
if let Some(m) = re.find(i) {
Ok((i.slice(m.end()..), i.slice(m.start()..m.end())))
} else {
Err(Err::Error(E::from_error_kind(i, ErrorKind::RegexpFind)))
}
}
}
#[cfg(all(feature = "regexp", feature = "alloc"))]
#[cfg_attr(
feature = "docsrs",
doc(cfg(all(feature = "regexp", feature = "alloc")))
)]
pub fn re_capture<'a, E>(re: Regex) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], Vec<&'a [u8]>, E>
where
E: ParseError<&'a [u8]>,
{
move |i| {
if let Some(c) = re.captures(i) {
let v: Vec<_> = c
.iter()
.filter(|el| el.is_some())
.map(|el| el.unwrap())
.map(|m| i.slice(m.start()..m.end()))
.collect();
let offset = {
let end = v.last().unwrap();
end.as_ptr() as usize + end.len() - i.as_ptr() as usize
};
Ok((i.slice(offset..), v))
} else {
Err(Err::Error(E::from_error_kind(i, ErrorKind::RegexpCapture)))
}
}
}
#[cfg(all(feature = "regexp", feature = "alloc"))]
#[cfg_attr(
feature = "docsrs",
doc(cfg(all(feature = "regexp", feature = "alloc")))
)]
pub fn re_captures<'a, E>(
re: Regex,
) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], Vec<Vec<&'a [u8]>>, E>
where
E: ParseError<&'a [u8]>,
{
move |i| {
let v: Vec<Vec<_>> = re
.captures_iter(i)
.map(|c| {
c.iter()
.filter(|el| el.is_some())
.map(|el| el.unwrap())
.map(|m| i.slice(m.start()..m.end()))
.collect()
})
.collect();
if !v.is_empty() {
let offset = {
let end = v.last().unwrap().last().unwrap();
end.as_ptr() as usize + end.len() - i.as_ptr() as usize
};
Ok((i.slice(offset..), v))
} else {
Err(Err::Error(E::from_error_kind(i, ErrorKind::RegexpCapture)))
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::error::ErrorKind;
use crate::internal::Err;
use crate::lib::regex::bytes::Regex;
macro_rules! assert_parse(
($left: expr, $right: expr) => {
let res: $crate::IResult<_, _, (_, ErrorKind)> = $left;
assert_eq!(res, $right);
};
);
#[test]
fn re_match_bytes() {
let re = Regex::new(r"^\d{4}-\d{2}-\d{2}").unwrap();
let rm = re_match(re);
assert_parse!(rm(&b"2015-09-07"[..]), Ok((&b""[..], &b"2015-09-07"[..])));
assert_eq!(
rm(&b"blah"[..]),
Err(Err::Error((&b"blah"[..], ErrorKind::RegexpMatch)))
);
assert_eq!(
rm(&b"2015-09-07blah"[..]),
Ok((&b""[..], &b"2015-09-07blah"[..]))
);
}
#[test]
fn re_find_bytes() {
let re = Regex::new(r"^\d{4}-\d{2}-\d{2}").unwrap();
let rm = re_find(re);
assert_parse!(rm(&b"2015-09-07"[..]), Ok((&b""[..], &b"2015-09-07"[..])));
assert_eq!(
rm(&b"blah"[..]),
Err(Err::Error((&b"blah"[..], ErrorKind::RegexpFind)))
);
assert_eq!(
rm(&b"2015-09-07blah"[..]),
Ok((&b"blah"[..], &b"2015-09-07"[..]))
);
}
#[cfg(feature = "alloc")]
#[test]
fn re_matches_bytes() {
let re = Regex::new(r"\d{4}-\d{2}-\d{2}").unwrap();
let rm = re_matches(re);
assert_parse!(
rm(&b"2015-09-07"[..]),
Ok((&b""[..], vec![&b"2015-09-07"[..]]))
);
assert_eq!(
rm(&b"blah"[..]),
Err(Err::Error((&b"blah"[..], ErrorKind::RegexpMatches)))
);
assert_eq!(
rm(&b"aaa2015-09-07blah2015-09-09pouet"[..]),
Ok((&b"pouet"[..], vec![&b"2015-09-07"[..], &b"2015-09-09"[..]]))
);
}
#[cfg(feature = "alloc")]
#[test]
fn re_capture_bytes() {
let re = Regex::new(r"([[:alpha:]]+)\s+((\d+).(\d+).(\d+))").unwrap();
let rm = re_capture(re);
assert_parse!(
rm(&b"blah nom 0.3.11pouet"[..]),
Ok((
&b"pouet"[..],
vec![
&b"nom 0.3.11"[..],
&b"nom"[..],
&b"0.3.11"[..],
&b"0"[..],
&b"3"[..],
&b"11"[..]
]
))
);
assert_eq!(
rm(&b"blah"[..]),
Err(Err::Error((&b"blah"[..], ErrorKind::RegexpCapture)))
);
assert_eq!(
rm(&b"hello nom 0.3.11 world regex 0.1.41"[..]),
Ok((
&b" world regex 0.1.41"[..],
vec![
&b"nom 0.3.11"[..],
&b"nom"[..],
&b"0.3.11"[..],
&b"0"[..],
&b"3"[..],
&b"11"[..]
]
))
);
}
#[cfg(feature = "alloc")]
#[test]
fn re_captures_bytes() {
let re = Regex::new(r"([[:alpha:]]+)\s+((\d+).(\d+).(\d+))").unwrap();
let rm = re_captures(re);
assert_parse!(
rm(&b"blah nom 0.3.11pouet"[..]),
Ok((
&b"pouet"[..],
vec![vec![
&b"nom 0.3.11"[..],
&b"nom"[..],
&b"0.3.11"[..],
&b"0"[..],
&b"3"[..],
&b"11"[..]
]]
))
);
assert_eq!(
rm(&b"blah"[..]),
Err(Err::Error((&b"blah"[..], ErrorKind::RegexpCapture)))
);
assert_eq!(
rm(&b"hello nom 0.3.11 world regex 0.1.41 aaa"[..]),
Ok((
&b" aaa"[..],
vec![
vec![
&b"nom 0.3.11"[..],
&b"nom"[..],
&b"0.3.11"[..],
&b"0"[..],
&b"3"[..],
&b"11"[..]
],
vec![
&b"regex 0.1.41"[..],
&b"regex"[..],
&b"0.1.41"[..],
&b"0"[..],
&b"1"[..],
&b"41"[..]
],
]
))
);
}
}
}