1#![allow(deprecated)]
4
5use crate::error::ErrorKind;
6use crate::error::ParseError;
7use crate::input::{
8 Compare, CompareResult, FindSubstring, FindToken, InputIter, InputLength, InputTake,
9 InputTakeAtPosition, IntoOutput, Slice, ToUsize,
10};
11use crate::lib::std::ops::RangeFrom;
12use crate::lib::std::result::Result::*;
13use crate::IntoOutputIResult;
14use crate::{Err, IResult, Parser};
15
16pub(crate) fn any<I, E: ParseError<I>>(input: I) -> IResult<I, <I as InputIter>::Item, E>
17where
18 I: InputIter + InputLength + Slice<RangeFrom<usize>>,
19{
20 let mut it = input.iter_indices();
21 match it.next() {
22 None => Err(Err::Error(E::from_error_kind(input, ErrorKind::Eof))),
23 Some((_, c)) => match it.next() {
24 None => Ok((input.slice(input.input_len()..), c)),
25 Some((idx, _)) => Ok((input.slice(idx..), c)),
26 },
27 }
28}
29
30#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bytes::tag`")]
52pub fn tag<T, Input, Error: ParseError<Input>>(
53 tag: T,
54) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
55where
56 Input: InputTake + Compare<T>,
57 Input: IntoOutput,
58 T: InputLength + Clone,
59{
60 move |i: Input| tag_internal(i, tag.clone())
61}
62
63pub(crate) fn tag_internal<T, Input, Error: ParseError<Input>>(
64 i: Input,
65 t: T,
66) -> IResult<Input, <Input as IntoOutput>::Output, Error>
67where
68 Input: InputTake + Compare<T>,
69 Input: IntoOutput,
70 T: InputLength,
71{
72 let tag_len = t.input_len();
73 let res: IResult<_, _, Error> = match i.compare(t) {
74 CompareResult::Ok => Ok(i.take_split(tag_len)),
75 _ => {
76 let e: ErrorKind = ErrorKind::Tag;
77 Err(Err::Error(Error::from_error_kind(i, e)))
78 }
79 };
80 res.into_output()
81}
82
83#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bytes::tag_no_case`")]
107pub fn tag_no_case<T, Input, Error: ParseError<Input>>(
108 tag: T,
109) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
110where
111 Input: InputTake + Compare<T>,
112 Input: IntoOutput,
113 T: InputLength + Clone,
114{
115 move |i: Input| tag_no_case_internal(i, tag.clone())
116}
117
118pub(crate) fn tag_no_case_internal<T, Input, Error: ParseError<Input>>(
119 i: Input,
120 t: T,
121) -> IResult<Input, <Input as IntoOutput>::Output, Error>
122where
123 Input: InputTake + Compare<T>,
124 Input: IntoOutput,
125 T: InputLength,
126{
127 let tag_len = t.input_len();
128
129 let res: IResult<_, _, Error> = match (i).compare_no_case(t) {
130 CompareResult::Ok => Ok(i.take_split(tag_len)),
131 _ => {
132 let e: ErrorKind = ErrorKind::Tag;
133 Err(Err::Error(Error::from_error_kind(i, e)))
134 }
135 };
136 res.into_output()
137}
138
139pub(crate) fn one_of_internal<I, T, E: ParseError<I>>(
140 input: I,
141 list: &T,
142) -> IResult<I, <I as InputIter>::Item, E>
143where
144 I: Slice<RangeFrom<usize>> + InputIter + InputLength,
145 <I as InputIter>::Item: Copy,
146 T: FindToken<<I as InputIter>::Item>,
147{
148 let mut it = input.iter_indices();
149 match it.next() {
150 Some((_, c)) if list.find_token(c) => match it.next() {
151 None => Ok((input.slice(input.input_len()..), c)),
152 Some((idx, _)) => Ok((input.slice(idx..), c)),
153 },
154 Some(_) => Err(Err::Error(E::from_error_kind(input, ErrorKind::OneOf))),
155 None => Err(Err::Error(E::from_error_kind(input, ErrorKind::OneOf))),
156 }
157}
158
159pub(crate) fn none_of_internal<I, T, E: ParseError<I>>(
160 input: I,
161 list: &T,
162) -> IResult<I, <I as InputIter>::Item, E>
163where
164 I: Slice<RangeFrom<usize>> + InputIter + InputLength,
165 <I as InputIter>::Item: Copy,
166 T: FindToken<<I as InputIter>::Item>,
167{
168 let mut it = input.iter_indices();
169 match it.next() {
170 Some((_, c)) if !list.find_token(c) => match it.next() {
171 None => Ok((input.slice(input.input_len()..), c)),
172 Some((idx, _)) => Ok((input.slice(idx..), c)),
173 },
174 Some(_) => Err(Err::Error(E::from_error_kind(input, ErrorKind::NoneOf))),
175 None => Err(Err::Error(E::from_error_kind(input, ErrorKind::NoneOf))),
176 }
177}
178
179#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bytes::take_till1`")]
203pub fn is_not<T, Input, Error: ParseError<Input>>(
204 arr: T,
205) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
206where
207 Input: InputTakeAtPosition,
208 Input: IntoOutput,
209 T: FindToken<<Input as InputTakeAtPosition>::Item>,
210{
211 move |i: Input| is_not_internal(i, &arr)
212}
213
214pub(crate) fn is_not_internal<T, Input, Error: ParseError<Input>>(
215 i: Input,
216 arr: &T,
217) -> IResult<Input, <Input as IntoOutput>::Output, Error>
218where
219 Input: InputTakeAtPosition,
220 Input: IntoOutput,
221 T: FindToken<<Input as InputTakeAtPosition>::Item>,
222{
223 let e: ErrorKind = ErrorKind::IsNot;
224 i.split_at_position1_complete(|c| arr.find_token(c), e)
225 .into_output()
226}
227
228#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bytes::take_while1`")]
252pub fn is_a<T, Input, Error: ParseError<Input>>(
253 arr: T,
254) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
255where
256 Input: InputTakeAtPosition,
257 Input: IntoOutput,
258 T: FindToken<<Input as InputTakeAtPosition>::Item>,
259{
260 move |i: Input| is_a_internal(i, &arr)
261}
262
263pub(crate) fn is_a_internal<T, Input, Error: ParseError<Input>>(
264 i: Input,
265 arr: &T,
266) -> IResult<Input, <Input as IntoOutput>::Output, Error>
267where
268 Input: InputTakeAtPosition,
269 Input: IntoOutput,
270 T: FindToken<<Input as InputTakeAtPosition>::Item>,
271{
272 let e: ErrorKind = ErrorKind::IsA;
273 i.split_at_position1_complete(|c| !arr.find_token(c), e)
274 .into_output()
275}
276
277#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bytes::take_while`")]
299pub fn take_while<T, Input, Error: ParseError<Input>>(
300 list: T,
301) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
302where
303 Input: InputTakeAtPosition,
304 Input: IntoOutput,
305 T: FindToken<<Input as InputTakeAtPosition>::Item>,
306{
307 move |i: Input| take_while_internal(i, &list)
308}
309
310pub(crate) fn take_while_internal<T, Input, Error: ParseError<Input>>(
311 i: Input,
312 list: &T,
313) -> IResult<Input, <Input as IntoOutput>::Output, Error>
314where
315 Input: InputTakeAtPosition,
316 Input: IntoOutput,
317 T: FindToken<<Input as InputTakeAtPosition>::Item>,
318{
319 i.split_at_position_complete(|c| !list.find_token(c))
320 .into_output()
321}
322
323#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bytes::take_while1`")]
346pub fn take_while1<T, Input, Error: ParseError<Input>>(
347 list: T,
348) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
349where
350 Input: InputTakeAtPosition,
351 Input: IntoOutput,
352 T: FindToken<<Input as InputTakeAtPosition>::Item>,
353{
354 move |i: Input| take_while1_internal(i, &list)
355}
356
357pub(crate) fn take_while1_internal<T, Input, Error: ParseError<Input>>(
358 i: Input,
359 list: &T,
360) -> IResult<Input, <Input as IntoOutput>::Output, Error>
361where
362 Input: InputTakeAtPosition,
363 Input: IntoOutput,
364 T: FindToken<<Input as InputTakeAtPosition>::Item>,
365{
366 let e: ErrorKind = ErrorKind::TakeWhile1;
367 i.split_at_position1_complete(|c| !list.find_token(c), e)
368 .into_output()
369}
370
371#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bytes::take_while_m_n`")]
397pub fn take_while_m_n<T, Input, Error: ParseError<Input>>(
398 m: usize,
399 n: usize,
400 list: T,
401) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
402where
403 Input: InputTake + InputIter + InputLength + Slice<RangeFrom<usize>>,
404 Input: IntoOutput,
405 T: FindToken<<Input as InputIter>::Item>,
406{
407 move |i: Input| take_while_m_n_internal(i, m, n, &list)
408}
409
410pub(crate) fn take_while_m_n_internal<T, Input, Error: ParseError<Input>>(
411 input: Input,
412 m: usize,
413 n: usize,
414 list: &T,
415) -> IResult<Input, <Input as IntoOutput>::Output, Error>
416where
417 Input: InputTake + InputIter + InputLength + Slice<RangeFrom<usize>>,
418 Input: IntoOutput,
419 T: FindToken<<Input as InputIter>::Item>,
420{
421 match input.position(|c| !list.find_token(c)) {
422 Some(idx) => {
423 if idx >= m {
424 if idx <= n {
425 let res: IResult<_, _, Error> = if let Ok(index) = input.slice_index(idx) {
426 Ok(input.take_split(index)).into_output()
427 } else {
428 Err(Err::Error(Error::from_error_kind(
429 input,
430 ErrorKind::TakeWhileMN,
431 )))
432 };
433 res
434 } else {
435 let res: IResult<_, _, Error> = if let Ok(index) = input.slice_index(n) {
436 Ok(input.take_split(index)).into_output()
437 } else {
438 Err(Err::Error(Error::from_error_kind(
439 input,
440 ErrorKind::TakeWhileMN,
441 )))
442 };
443 res
444 }
445 } else {
446 let e = ErrorKind::TakeWhileMN;
447 Err(Err::Error(Error::from_error_kind(input, e)))
448 }
449 }
450 None => {
451 let len = input.input_len();
452 if len >= n {
453 match input.slice_index(n) {
454 Ok(index) => Ok(input.take_split(index)).into_output(),
455 Err(_needed) => Err(Err::Error(Error::from_error_kind(
456 input,
457 ErrorKind::TakeWhileMN,
458 ))),
459 }
460 } else if len >= m && len <= n {
461 let res: IResult<_, _, Error> = Ok((input.slice(len..), input));
462 res.into_output()
463 } else {
464 let e = ErrorKind::TakeWhileMN;
465 Err(Err::Error(Error::from_error_kind(input, e)))
466 }
467 }
468 }
469}
470
471#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bytes::take_till`")]
492pub fn take_till<T, Input, Error: ParseError<Input>>(
493 list: T,
494) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
495where
496 Input: InputTakeAtPosition,
497 Input: IntoOutput,
498 T: FindToken<<Input as InputTakeAtPosition>::Item>,
499{
500 move |i: Input| take_till_internal(i, &list)
501}
502
503pub(crate) fn take_till_internal<T, Input, Error: ParseError<Input>>(
504 i: Input,
505 list: &T,
506) -> IResult<Input, <Input as IntoOutput>::Output, Error>
507where
508 Input: InputTakeAtPosition,
509 Input: IntoOutput,
510 T: FindToken<<Input as InputTakeAtPosition>::Item>,
511{
512 i.split_at_position_complete(|c| list.find_token(c))
513 .into_output()
514}
515
516#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bytes::take_till1`")]
540pub fn take_till1<T, Input, Error: ParseError<Input>>(
541 list: T,
542) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
543where
544 Input: InputTakeAtPosition,
545 Input: IntoOutput,
546 T: FindToken<<Input as InputTakeAtPosition>::Item>,
547{
548 move |i: Input| take_till1_internal(i, &list)
549}
550
551pub(crate) fn take_till1_internal<T, Input, Error: ParseError<Input>>(
552 i: Input,
553 list: &T,
554) -> IResult<Input, <Input as IntoOutput>::Output, Error>
555where
556 Input: InputTakeAtPosition,
557 Input: IntoOutput,
558 T: FindToken<<Input as InputTakeAtPosition>::Item>,
559{
560 let e: ErrorKind = ErrorKind::TakeTill1;
561 i.split_at_position1_complete(|c| list.find_token(c), e)
562 .into_output()
563}
564
565#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bytes::take`")]
597pub fn take<C, Input, Error: ParseError<Input>>(
598 count: C,
599) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
600where
601 Input: InputIter + InputTake,
602 Input: IntoOutput,
603 C: ToUsize,
604{
605 let c = count.to_usize();
606 move |i: Input| take_internal(i, c)
607}
608
609pub(crate) fn take_internal<Input, Error: ParseError<Input>>(
610 i: Input,
611 c: usize,
612) -> IResult<Input, <Input as IntoOutput>::Output, Error>
613where
614 Input: InputIter + InputTake,
615 Input: IntoOutput,
616{
617 match i.slice_index(c) {
618 Err(_needed) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::Eof))),
619 Ok(index) => Ok(i.take_split(index)).into_output(),
620 }
621}
622
623#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bytes::take_until`")]
644pub fn take_until<T, Input, Error: ParseError<Input>>(
645 tag: T,
646) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
647where
648 Input: InputTake + FindSubstring<T>,
649 Input: IntoOutput,
650 T: InputLength + Clone,
651{
652 move |i: Input| take_until_internal(i, tag.clone())
653}
654
655pub(crate) fn take_until_internal<T, Input, Error: ParseError<Input>>(
656 i: Input,
657 t: T,
658) -> IResult<Input, <Input as IntoOutput>::Output, Error>
659where
660 Input: InputTake + FindSubstring<T>,
661 Input: IntoOutput,
662 T: InputLength,
663{
664 let res: IResult<_, _, Error> = match i.find_substring(t) {
665 None => Err(Err::Error(Error::from_error_kind(i, ErrorKind::TakeUntil))),
666 Some(index) => Ok(i.take_split(index)),
667 };
668 res.into_output()
669}
670
671#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bytes::take_until1`")]
693pub fn take_until1<T, Input, Error: ParseError<Input>>(
694 tag: T,
695) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
696where
697 Input: InputTake + FindSubstring<T>,
698 Input: IntoOutput,
699 T: InputLength + Clone,
700{
701 move |i: Input| take_until1_internal(i, tag.clone())
702}
703
704pub(crate) fn take_until1_internal<T, Input, Error: ParseError<Input>>(
705 i: Input,
706 t: T,
707) -> IResult<Input, <Input as IntoOutput>::Output, Error>
708where
709 Input: InputTake + FindSubstring<T>,
710 Input: IntoOutput,
711 T: InputLength,
712{
713 let res: IResult<_, _, Error> = match i.find_substring(t) {
714 None => Err(Err::Error(Error::from_error_kind(i, ErrorKind::TakeUntil))),
715 Some(0) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::TakeUntil))),
716 Some(index) => Ok(i.take_split(index)),
717 };
718 res.into_output()
719}
720
721#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bytes::escaped`")]
744pub fn escaped<'a, Input: 'a, Error, F, G, O1, O2>(
745 mut normal: F,
746 control_char: char,
747 mut escapable: G,
748) -> impl FnMut(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
749where
750 Input: Clone
751 + crate::input::Offset
752 + InputLength
753 + InputTake
754 + InputTakeAtPosition
755 + Slice<RangeFrom<usize>>
756 + InputIter,
757 Input: IntoOutput,
758 <Input as InputIter>::Item: crate::input::AsChar,
759 F: Parser<Input, O1, Error>,
760 G: Parser<Input, O2, Error>,
761 Error: ParseError<Input>,
762{
763 move |input: Input| escaped_internal(input, &mut normal, control_char, &mut escapable)
764}
765
766pub(crate) fn escaped_internal<'a, Input: 'a, Error, F, G, O1, O2>(
767 input: Input,
768 normal: &mut F,
769 control_char: char,
770 escapable: &mut G,
771) -> IResult<Input, <Input as IntoOutput>::Output, Error>
772where
773 Input: Clone
774 + crate::input::Offset
775 + InputLength
776 + InputTake
777 + InputTakeAtPosition
778 + Slice<RangeFrom<usize>>
779 + InputIter,
780 Input: IntoOutput,
781 <Input as InputIter>::Item: crate::input::AsChar,
782 F: Parser<Input, O1, Error>,
783 G: Parser<Input, O2, Error>,
784 Error: ParseError<Input>,
785{
786 use crate::input::AsChar;
787
788 let mut i = input.clone();
789
790 while i.input_len() > 0 {
791 let current_len = i.input_len();
792
793 match normal.parse(i.clone()) {
794 Ok((i2, _)) => {
795 if i2.input_len() == 0 {
798 return Ok((input.slice(input.input_len()..), input)).into_output();
799 } else if i2.input_len() == current_len {
800 let index = input.offset(&i2);
801 return Ok(input.take_split(index)).into_output();
802 } else {
803 i = i2;
804 }
805 }
806 Err(Err::Error(_)) => {
807 if i.iter_elements().next().unwrap().as_char() == control_char {
809 let next = control_char.len_utf8();
810 if next >= i.input_len() {
811 return Err(Err::Error(Error::from_error_kind(
812 input,
813 ErrorKind::Escaped,
814 )));
815 } else {
816 match escapable.parse(i.slice(next..)) {
817 Ok((i2, _)) => {
818 if i2.input_len() == 0 {
819 return Ok((input.slice(input.input_len()..), input)).into_output();
820 } else {
821 i = i2;
822 }
823 }
824 Err(e) => return Err(e),
825 }
826 }
827 } else {
828 let index = input.offset(&i);
829 if index == 0 {
830 return Err(Err::Error(Error::from_error_kind(
831 input,
832 ErrorKind::Escaped,
833 )));
834 }
835 return Ok(input.take_split(index)).into_output();
836 }
837 }
838 Err(e) => {
839 return Err(e);
840 }
841 }
842 }
843
844 Ok((input.slice(input.input_len()..), input)).into_output()
845}
846
847#[cfg(feature = "alloc")]
879#[deprecated(
882 since = "8.0.0",
883 note = "Replaced with `nom8::bytes::escaped_transform`"
884)]
885pub fn escaped_transform<Input, Error, F, G, O1, O2, ExtendItem, Output>(
886 mut normal: F,
887 control_char: char,
888 mut transform: G,
889) -> impl FnMut(Input) -> IResult<Input, Output, Error>
890where
891 Input: Clone
892 + crate::input::Offset
893 + InputLength
894 + InputTake
895 + InputTakeAtPosition
896 + Slice<RangeFrom<usize>>
897 + InputIter,
898 Input: crate::input::ExtendInto<Item = ExtendItem, Extender = Output>,
899 O1: crate::input::ExtendInto<Item = ExtendItem, Extender = Output>,
900 O2: crate::input::ExtendInto<Item = ExtendItem, Extender = Output>,
901 <Input as InputIter>::Item: crate::input::AsChar,
902 F: Parser<Input, O1, Error>,
903 G: Parser<Input, O2, Error>,
904 Error: ParseError<Input>,
905{
906 move |input: Input| escaped_transform_internal(input, &mut normal, control_char, &mut transform)
907}
908
909#[cfg(feature = "alloc")]
910pub(crate) fn escaped_transform_internal<Input, Error, F, G, O1, O2, ExtendItem, Output>(
911 input: Input,
912 normal: &mut F,
913 control_char: char,
914 transform: &mut G,
915) -> IResult<Input, Output, Error>
916where
917 Input: Clone
918 + crate::input::Offset
919 + InputLength
920 + InputTake
921 + InputTakeAtPosition
922 + Slice<RangeFrom<usize>>
923 + InputIter,
924 Input: crate::input::ExtendInto<Item = ExtendItem, Extender = Output>,
925 O1: crate::input::ExtendInto<Item = ExtendItem, Extender = Output>,
926 O2: crate::input::ExtendInto<Item = ExtendItem, Extender = Output>,
927 <Input as InputIter>::Item: crate::input::AsChar,
928 F: Parser<Input, O1, Error>,
929 G: Parser<Input, O2, Error>,
930 Error: ParseError<Input>,
931{
932 use crate::input::AsChar;
933
934 let mut index = 0;
935 let mut res = input.new_builder();
936
937 let i = input.clone();
938
939 while index < i.input_len() {
940 let current_len = i.input_len();
941 let remainder = i.slice(index..);
942 match normal.parse(remainder.clone()) {
943 Ok((i2, o)) => {
944 o.extend_into(&mut res);
945 if i2.input_len() == 0 {
946 return Ok((i.slice(i.input_len()..), res));
947 } else if i2.input_len() == current_len {
948 return Ok((remainder, res));
949 } else {
950 index = input.offset(&i2);
951 }
952 }
953 Err(Err::Error(_)) => {
954 if remainder.iter_elements().next().unwrap().as_char() == control_char {
956 let next = index + control_char.len_utf8();
957 let input_len = input.input_len();
958
959 if next >= input_len {
960 return Err(Err::Error(Error::from_error_kind(
961 remainder,
962 ErrorKind::EscapedTransform,
963 )));
964 } else {
965 match transform.parse(i.slice(next..)) {
966 Ok((i2, o)) => {
967 o.extend_into(&mut res);
968 if i2.input_len() == 0 {
969 return Ok((i.slice(i.input_len()..), res));
970 } else {
971 index = input.offset(&i2);
972 }
973 }
974 Err(e) => return Err(e),
975 }
976 }
977 } else {
978 if index == 0 {
979 return Err(Err::Error(Error::from_error_kind(
980 remainder,
981 ErrorKind::EscapedTransform,
982 )));
983 }
984 return Ok((remainder, res));
985 }
986 }
987 Err(e) => return Err(e),
988 }
989 }
990 Ok((input.slice(index..), res))
991}
992
993#[cfg(test)]
994mod tests {
995 use super::*;
996 use crate::character::complete::{alpha1 as alpha, digit1 as digit};
997 #[cfg(feature = "alloc")]
998 use crate::{
999 branch::alt,
1000 combinator::{map, value},
1001 lib::std::string::String,
1002 lib::std::vec::Vec,
1003 };
1004
1005 #[test]
1006 fn complete_take_while_m_n_utf8_all_matching() {
1007 let result: IResult<&str, &str> =
1008 super::take_while_m_n(1, 4, |c: char| c.is_alphabetic())("øn");
1009 assert_eq!(result, Ok(("", "øn")));
1010 }
1011
1012 #[test]
1013 fn complete_take_while_m_n_utf8_all_matching_substring() {
1014 let result: IResult<&str, &str> =
1015 super::take_while_m_n(1, 1, |c: char| c.is_alphabetic())("øn");
1016 assert_eq!(result, Ok(("n", "ø")));
1017 }
1018
1019 fn escaped_string(input: &str) -> IResult<&str, &str> {
1021 use crate::character::complete::{alpha0, one_of};
1022 escaped(alpha0, '\\', one_of("n"))(input)
1023 }
1024
1025 #[test]
1027 fn escaped_hang() {
1028 escaped_string("7").unwrap();
1029 escaped_string("a7").unwrap();
1030 }
1031
1032 fn unquote<'a>(input: &'a str) -> IResult<&'a str, &'a str> {
1034 use crate::bytes::complete::*;
1035 use crate::character::complete::*;
1036 use crate::combinator::opt;
1037 use crate::sequence::delimited;
1038
1039 delimited(
1040 char('"'),
1041 escaped(opt(none_of(r#"\""#)), '\\', one_of(r#"\"rnt"#)),
1042 char('"'),
1043 )(input)
1044 }
1045
1046 #[test]
1047 fn escaped_hang_1118() {
1048 assert_eq!(unquote(r#""""#), Ok(("", "")));
1049 }
1050
1051 #[cfg(feature = "alloc")]
1052 #[allow(unused_variables)]
1053 #[test]
1054 fn escaping() {
1055 use crate::character::complete::one_of;
1056
1057 fn esc(i: &[u8]) -> IResult<&[u8], &[u8]> {
1058 escaped(alpha, '\\', one_of("\"n\\"))(i)
1059 }
1060 assert_eq!(esc(&b"abcd;"[..]), Ok((&b";"[..], &b"abcd"[..])));
1061 assert_eq!(esc(&b"ab\\\"cd;"[..]), Ok((&b";"[..], &b"ab\\\"cd"[..])));
1062 assert_eq!(esc(&b"\\\"abcd;"[..]), Ok((&b";"[..], &b"\\\"abcd"[..])));
1063 assert_eq!(esc(&b"\\n;"[..]), Ok((&b";"[..], &b"\\n"[..])));
1064 assert_eq!(esc(&b"ab\\\"12"[..]), Ok((&b"12"[..], &b"ab\\\""[..])));
1065 assert_eq!(
1066 esc(&b"AB\\"[..]),
1067 Err(Err::Error(error_position!(
1068 &b"AB\\"[..],
1069 ErrorKind::Escaped
1070 )))
1071 );
1072 assert_eq!(
1073 esc(&b"AB\\A"[..]),
1074 Err(Err::Error(error_node_position!(
1075 &b"AB\\A"[..],
1076 ErrorKind::Escaped,
1077 error_position!(&b"A"[..], ErrorKind::OneOf)
1078 )))
1079 );
1080
1081 fn esc2(i: &[u8]) -> IResult<&[u8], &[u8]> {
1082 escaped(digit, '\\', one_of("\"n\\"))(i)
1083 }
1084 assert_eq!(esc2(&b"12\\nnn34"[..]), Ok((&b"nn34"[..], &b"12\\n"[..])));
1085 }
1086
1087 #[cfg(feature = "alloc")]
1088 #[test]
1089 fn escaping_str() {
1090 use crate::character::complete::one_of;
1091
1092 fn esc(i: &str) -> IResult<&str, &str> {
1093 escaped(alpha, '\\', one_of("\"n\\"))(i)
1094 }
1095 assert_eq!(esc("abcd;"), Ok((";", "abcd")));
1096 assert_eq!(esc("ab\\\"cd;"), Ok((";", "ab\\\"cd")));
1097 assert_eq!(esc("\\\"abcd;"), Ok((";", "\\\"abcd")));
1098 assert_eq!(esc("\\n;"), Ok((";", "\\n")));
1099 assert_eq!(esc("ab\\\"12"), Ok(("12", "ab\\\"")));
1100 assert_eq!(
1101 esc("AB\\"),
1102 Err(Err::Error(error_position!("AB\\", ErrorKind::Escaped)))
1103 );
1104 assert_eq!(
1105 esc("AB\\A"),
1106 Err(Err::Error(error_node_position!(
1107 "AB\\A",
1108 ErrorKind::Escaped,
1109 error_position!("A", ErrorKind::OneOf)
1110 )))
1111 );
1112
1113 fn esc2(i: &str) -> IResult<&str, &str> {
1114 escaped(digit, '\\', one_of("\"n\\"))(i)
1115 }
1116 assert_eq!(esc2("12\\nnn34"), Ok(("nn34", "12\\n")));
1117
1118 fn esc3(i: &str) -> IResult<&str, &str> {
1119 escaped(alpha, '\u{241b}', one_of("\"n"))(i)
1120 }
1121 assert_eq!(esc3("abâncd;"), Ok((";", "abâncd")));
1122 }
1123
1124 #[cfg(feature = "alloc")]
1125 fn to_s(i: Vec<u8>) -> String {
1126 String::from_utf8_lossy(&i).into_owned()
1127 }
1128
1129 #[cfg(feature = "alloc")]
1130 #[test]
1131 fn escape_transform() {
1132 fn esc(i: &[u8]) -> IResult<&[u8], String> {
1133 map(
1134 escaped_transform(
1135 alpha,
1136 '\\',
1137 alt((
1138 value(&b"\\"[..], tag("\\")),
1139 value(&b"\""[..], tag("\"")),
1140 value(&b"\n"[..], tag("n")),
1141 )),
1142 ),
1143 to_s,
1144 )(i)
1145 }
1146
1147 assert_eq!(esc(&b"abcd;"[..]), Ok((&b";"[..], String::from("abcd"))));
1148 assert_eq!(
1149 esc(&b"ab\\\"cd;"[..]),
1150 Ok((&b";"[..], String::from("ab\"cd")))
1151 );
1152 assert_eq!(
1153 esc(&b"\\\"abcd;"[..]),
1154 Ok((&b";"[..], String::from("\"abcd")))
1155 );
1156 assert_eq!(esc(&b"\\n;"[..]), Ok((&b";"[..], String::from("\n"))));
1157 assert_eq!(
1158 esc(&b"ab\\\"12"[..]),
1159 Ok((&b"12"[..], String::from("ab\"")))
1160 );
1161 assert_eq!(
1162 esc(&b"AB\\"[..]),
1163 Err(Err::Error(error_position!(
1164 &b"\\"[..],
1165 ErrorKind::EscapedTransform
1166 )))
1167 );
1168 assert_eq!(
1169 esc(&b"AB\\A"[..]),
1170 Err(Err::Error(error_node_position!(
1171 &b"AB\\A"[..],
1172 ErrorKind::EscapedTransform,
1173 error_position!(&b"A"[..], ErrorKind::Tag)
1174 )))
1175 );
1176
1177 fn esc2(i: &[u8]) -> IResult<&[u8], String> {
1178 map(
1179 escaped_transform(
1180 alpha,
1181 '&',
1182 alt((
1183 value("è".as_bytes(), tag("egrave;")),
1184 value("Ă ".as_bytes(), tag("agrave;")),
1185 )),
1186 ),
1187 to_s,
1188 )(i)
1189 }
1190 assert_eq!(
1191 esc2(&b"abèDEF;"[..]),
1192 Ok((&b";"[..], String::from("abèDEF")))
1193 );
1194 assert_eq!(
1195 esc2(&b"abèDàEF;"[..]),
1196 Ok((&b";"[..], String::from("abèDà EF")))
1197 );
1198 }
1199
1200 #[cfg(feature = "std")]
1201 #[test]
1202 fn escape_transform_str() {
1203 fn esc(i: &str) -> IResult<&str, String> {
1204 escaped_transform(
1205 alpha,
1206 '\\',
1207 alt((
1208 value("\\", tag("\\")),
1209 value("\"", tag("\"")),
1210 value("\n", tag("n")),
1211 )),
1212 )(i)
1213 }
1214
1215 assert_eq!(esc("abcd;"), Ok((";", String::from("abcd"))));
1216 assert_eq!(esc("ab\\\"cd;"), Ok((";", String::from("ab\"cd"))));
1217 assert_eq!(esc("\\\"abcd;"), Ok((";", String::from("\"abcd"))));
1218 assert_eq!(esc("\\n;"), Ok((";", String::from("\n"))));
1219 assert_eq!(esc("ab\\\"12"), Ok(("12", String::from("ab\""))));
1220 assert_eq!(
1221 esc("AB\\"),
1222 Err(Err::Error(error_position!(
1223 "\\",
1224 ErrorKind::EscapedTransform
1225 )))
1226 );
1227 assert_eq!(
1228 esc("AB\\A"),
1229 Err(Err::Error(error_node_position!(
1230 "AB\\A",
1231 ErrorKind::EscapedTransform,
1232 error_position!("A", ErrorKind::Tag)
1233 )))
1234 );
1235
1236 fn esc2(i: &str) -> IResult<&str, String> {
1237 escaped_transform(
1238 alpha,
1239 '&',
1240 alt((value("è", tag("egrave;")), value("à ", tag("agrave;")))),
1241 )(i)
1242 }
1243 assert_eq!(esc2("abèDEF;"), Ok((";", String::from("abèDEF"))));
1244 assert_eq!(
1245 esc2("abèDàEF;"),
1246 Ok((";", String::from("abèDà EF")))
1247 );
1248
1249 fn esc3(i: &str) -> IResult<&str, String> {
1250 escaped_transform(
1251 alpha,
1252 'â',
1253 alt((value("\0", tag("0")), value("\n", tag("n")))),
1254 )(i)
1255 }
1256 assert_eq!(esc3("aâ0bcân"), Ok(("", String::from("a\0bc\n"))));
1257 }
1258}