16855e09eSopenharmony_ciuse crate::branch::{alt, permutation};
26855e09eSopenharmony_ciuse crate::bytes::streaming::tag;
36855e09eSopenharmony_ciuse crate::error::ErrorKind;
46855e09eSopenharmony_ciuse crate::internal::{Err, IResult, Needed};
56855e09eSopenharmony_ci#[cfg(feature = "alloc")]
66855e09eSopenharmony_ciuse crate::{
76855e09eSopenharmony_ci  error::ParseError,
86855e09eSopenharmony_ci  lib::std::{
96855e09eSopenharmony_ci    fmt::Debug,
106855e09eSopenharmony_ci    string::{String, ToString},
116855e09eSopenharmony_ci  },
126855e09eSopenharmony_ci};
136855e09eSopenharmony_ci
146855e09eSopenharmony_ci#[cfg(feature = "alloc")]
156855e09eSopenharmony_ci#[derive(Debug, Clone, PartialEq)]
166855e09eSopenharmony_cipub struct ErrorStr(String);
176855e09eSopenharmony_ci
186855e09eSopenharmony_ci#[cfg(feature = "alloc")]
196855e09eSopenharmony_ciimpl From<u32> for ErrorStr {
206855e09eSopenharmony_ci  fn from(i: u32) -> Self {
216855e09eSopenharmony_ci    ErrorStr(format!("custom error code: {}", i))
226855e09eSopenharmony_ci  }
236855e09eSopenharmony_ci}
246855e09eSopenharmony_ci
256855e09eSopenharmony_ci#[cfg(feature = "alloc")]
266855e09eSopenharmony_ciimpl<'a> From<&'a str> for ErrorStr {
276855e09eSopenharmony_ci  fn from(i: &'a str) -> Self {
286855e09eSopenharmony_ci    ErrorStr(format!("custom error message: {}", i))
296855e09eSopenharmony_ci  }
306855e09eSopenharmony_ci}
316855e09eSopenharmony_ci
326855e09eSopenharmony_ci#[cfg(feature = "alloc")]
336855e09eSopenharmony_ciimpl<I: Debug> ParseError<I> for ErrorStr {
346855e09eSopenharmony_ci  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
356855e09eSopenharmony_ci    ErrorStr(format!("custom error message: ({:?}, {:?})", input, kind))
366855e09eSopenharmony_ci  }
376855e09eSopenharmony_ci
386855e09eSopenharmony_ci  fn append(input: I, kind: ErrorKind, other: Self) -> Self {
396855e09eSopenharmony_ci    ErrorStr(format!(
406855e09eSopenharmony_ci      "custom error message: ({:?}, {:?}) - {:?}",
416855e09eSopenharmony_ci      input, kind, other
426855e09eSopenharmony_ci    ))
436855e09eSopenharmony_ci  }
446855e09eSopenharmony_ci}
456855e09eSopenharmony_ci
466855e09eSopenharmony_ci#[cfg(feature = "alloc")]
476855e09eSopenharmony_ci#[test]
486855e09eSopenharmony_cifn alt_test() {
496855e09eSopenharmony_ci  fn work(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> {
506855e09eSopenharmony_ci    Ok((&b""[..], input))
516855e09eSopenharmony_ci  }
526855e09eSopenharmony_ci
536855e09eSopenharmony_ci  #[allow(unused_variables)]
546855e09eSopenharmony_ci  fn dont_work(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> {
556855e09eSopenharmony_ci    Err(Err::Error(ErrorStr("abcd".to_string())))
566855e09eSopenharmony_ci  }
576855e09eSopenharmony_ci
586855e09eSopenharmony_ci  fn work2(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> {
596855e09eSopenharmony_ci    Ok((input, &b""[..]))
606855e09eSopenharmony_ci  }
616855e09eSopenharmony_ci
626855e09eSopenharmony_ci  fn alt1(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> {
636855e09eSopenharmony_ci    alt((dont_work, dont_work))(i)
646855e09eSopenharmony_ci  }
656855e09eSopenharmony_ci  fn alt2(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> {
666855e09eSopenharmony_ci    alt((dont_work, work))(i)
676855e09eSopenharmony_ci  }
686855e09eSopenharmony_ci  fn alt3(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> {
696855e09eSopenharmony_ci    alt((dont_work, dont_work, work2, dont_work))(i)
706855e09eSopenharmony_ci  }
716855e09eSopenharmony_ci  //named!(alt1, alt!(dont_work | dont_work));
726855e09eSopenharmony_ci  //named!(alt2, alt!(dont_work | work));
736855e09eSopenharmony_ci  //named!(alt3, alt!(dont_work | dont_work | work2 | dont_work));
746855e09eSopenharmony_ci
756855e09eSopenharmony_ci  let a = &b"abcd"[..];
766855e09eSopenharmony_ci  assert_eq!(
776855e09eSopenharmony_ci    alt1(a),
786855e09eSopenharmony_ci    Err(Err::Error(error_node_position!(
796855e09eSopenharmony_ci      a,
806855e09eSopenharmony_ci      ErrorKind::Alt,
816855e09eSopenharmony_ci      ErrorStr("abcd".to_string())
826855e09eSopenharmony_ci    )))
836855e09eSopenharmony_ci  );
846855e09eSopenharmony_ci  assert_eq!(alt2(a), Ok((&b""[..], a)));
856855e09eSopenharmony_ci  assert_eq!(alt3(a), Ok((a, &b""[..])));
866855e09eSopenharmony_ci
876855e09eSopenharmony_ci  fn alt4(i: &[u8]) -> IResult<&[u8], &[u8]> {
886855e09eSopenharmony_ci    alt((tag("abcd"), tag("efgh")))(i)
896855e09eSopenharmony_ci  }
906855e09eSopenharmony_ci  let b = &b"efgh"[..];
916855e09eSopenharmony_ci  assert_eq!(alt4(a), Ok((&b""[..], a)));
926855e09eSopenharmony_ci  assert_eq!(alt4(b), Ok((&b""[..], b)));
936855e09eSopenharmony_ci}
946855e09eSopenharmony_ci
956855e09eSopenharmony_ci#[test]
966855e09eSopenharmony_cifn alt_incomplete() {
976855e09eSopenharmony_ci  fn alt1(i: &[u8]) -> IResult<&[u8], &[u8]> {
986855e09eSopenharmony_ci    alt((tag("a"), tag("bc"), tag("def")))(i)
996855e09eSopenharmony_ci  }
1006855e09eSopenharmony_ci
1016855e09eSopenharmony_ci  let a = &b""[..];
1026855e09eSopenharmony_ci  assert_eq!(alt1(a), Err(Err::Incomplete(Needed::new(1))));
1036855e09eSopenharmony_ci  let a = &b"b"[..];
1046855e09eSopenharmony_ci  assert_eq!(alt1(a), Err(Err::Incomplete(Needed::new(1))));
1056855e09eSopenharmony_ci  let a = &b"bcd"[..];
1066855e09eSopenharmony_ci  assert_eq!(alt1(a), Ok((&b"d"[..], &b"bc"[..])));
1076855e09eSopenharmony_ci  let a = &b"cde"[..];
1086855e09eSopenharmony_ci  assert_eq!(alt1(a), Err(Err::Error(error_position!(a, ErrorKind::Tag))));
1096855e09eSopenharmony_ci  let a = &b"de"[..];
1106855e09eSopenharmony_ci  assert_eq!(alt1(a), Err(Err::Incomplete(Needed::new(1))));
1116855e09eSopenharmony_ci  let a = &b"defg"[..];
1126855e09eSopenharmony_ci  assert_eq!(alt1(a), Ok((&b"g"[..], &b"def"[..])));
1136855e09eSopenharmony_ci}
1146855e09eSopenharmony_ci
1156855e09eSopenharmony_ci#[test]
1166855e09eSopenharmony_cifn permutation_test() {
1176855e09eSopenharmony_ci  fn perm(i: &[u8]) -> IResult<&[u8], (&[u8], &[u8], &[u8])> {
1186855e09eSopenharmony_ci    permutation((tag("abcd"), tag("efg"), tag("hi")))(i)
1196855e09eSopenharmony_ci  }
1206855e09eSopenharmony_ci
1216855e09eSopenharmony_ci  let expected = (&b"abcd"[..], &b"efg"[..], &b"hi"[..]);
1226855e09eSopenharmony_ci
1236855e09eSopenharmony_ci  let a = &b"abcdefghijk"[..];
1246855e09eSopenharmony_ci  assert_eq!(perm(a), Ok((&b"jk"[..], expected)));
1256855e09eSopenharmony_ci  let b = &b"efgabcdhijk"[..];
1266855e09eSopenharmony_ci  assert_eq!(perm(b), Ok((&b"jk"[..], expected)));
1276855e09eSopenharmony_ci  let c = &b"hiefgabcdjk"[..];
1286855e09eSopenharmony_ci  assert_eq!(perm(c), Ok((&b"jk"[..], expected)));
1296855e09eSopenharmony_ci
1306855e09eSopenharmony_ci  let d = &b"efgxyzabcdefghi"[..];
1316855e09eSopenharmony_ci  assert_eq!(
1326855e09eSopenharmony_ci    perm(d),
1336855e09eSopenharmony_ci    Err(Err::Error(error_node_position!(
1346855e09eSopenharmony_ci      &b"efgxyzabcdefghi"[..],
1356855e09eSopenharmony_ci      ErrorKind::Permutation,
1366855e09eSopenharmony_ci      error_position!(&b"xyzabcdefghi"[..], ErrorKind::Tag)
1376855e09eSopenharmony_ci    )))
1386855e09eSopenharmony_ci  );
1396855e09eSopenharmony_ci
1406855e09eSopenharmony_ci  let e = &b"efgabc"[..];
1416855e09eSopenharmony_ci  assert_eq!(perm(e), Err(Err::Incomplete(Needed::new(1))));
1426855e09eSopenharmony_ci}
143