1use crate::tuple::PartThen;
2use bogobble::*;
3use std::fmt::Display;
4use std::marker::PhantomData;
5
6pub type SSRes<'a> = Result<(PIter<'a>, Option<PErr<'a>>), PErr<'a>>;
7
8pub trait SSErr<'a>: Sized {
9 fn join_err(self, e2: PErr<'a>) -> Self;
10 fn join_err_op(self, e: Option<PErr<'a>>) -> Self {
11 match e {
12 Some(e) => self.join_err(e),
13 None => self,
14 }
15 }
16 fn put(self, res: &mut String, it: &PIter) -> Self;
17}
18
19pub trait BackTo {
20 fn back(&self, _: usize) {}
21}
22
23impl BackTo for () {}
24
25impl<'a> SSErr<'a> for SSRes<'a> {
26 fn join_err(self, e2: PErr<'a>) -> Self {
27 self.map_err(|e| e.join(e2))
28 }
29 fn put(self, res: &mut String, it: &PIter) -> Self {
30 if let Ok((i, _)) = &self {
31 res.push_str(it.str_to(i.index()));
32 }
33 self
34 }
35}
36
37pub trait SSParser<CF: BackTo>: Sized {
38 fn ss_parse<'a>(&self, i: &PIter<'a>, res: &mut String, _: &CF) -> SSRes<'a>;
39
40 fn ss_convert<'a>(&self, s: &'a str, cf: &CF) -> Result<String, PErr<'a>> {
41 let mut res = String::new();
42 let it = PIter::new(s);
43 match self.ss_parse(&it, &mut res, cf) {
44 Ok(_) => Ok(res),
45 Err(e) => Err(e),
46 }
47 }
48}
49
50pub trait SSOrer: Sized {
51 fn ss_or<B>(self, b: B) -> SSOR<Self, B> {
52 SSOR(self, b)
53 }
54 fn p_then<B>(self, b: B) -> PartThen<Self, B> {
55 PartThen(self, b)
56 }
57}
58
59impl<T: Sized> SSOrer for T {}
60
61pub struct SS<P: OParser<T>, T>(P, PhantomData<T>);
62
63pub fn ss<P: OParser<T>, T>(p: P) -> SS<P, T> {
64 SS(p, PhantomData)
65}
66
67impl<P: OParser<T>, T, CF: BackTo> SSParser<CF> for SS<P, T> {
68 fn ss_parse<'a>(&self, i: &PIter<'a>, res: &mut String, _: &CF) -> SSRes<'a> {
69 match self.0.parse(i) {
70 Ok((i2, _, e)) => {
71 res.push_str(i.str_to(i2.index()));
72 Ok((i2, e))
73 }
74 Err(e) => Err(e),
75 }
76 }
77}
78
79pub struct Put<T: Display>(pub T);
80
81impl<T: Display, CF: BackTo> SSParser<CF> for Put<T> {
82 fn ss_parse<'a>(&self, i: &PIter<'a>, res: &mut String, _: &CF) -> SSRes<'a> {
83 res.push_str(&self.0.to_string());
84 Ok((i.clone(), None))
85 }
86}
87
88pub struct SSkip<P: OParser<T>, T>(P, PhantomData<T>);
89
90pub fn sskip<P: OParser<T>, T>(p: P) -> SSkip<P, T> {
91 SSkip(p, PhantomData)
92}
93
94impl<P: OParser<T>, T, CF: BackTo> SSParser<CF> for SSkip<P, T> {
95 fn ss_parse<'a>(&self, i: &PIter<'a>, _: &mut String, _: &CF) -> SSRes<'a> {
96 match self.0.parse(i) {
97 Ok((i2, _, e)) => Ok((i2, e)),
98 Err(e) => Err(e),
99 }
100 }
101}
102
103pub struct SSOR<A, B>(A, B);
104
105impl<CF: BackTo, A: SSParser<CF>, B: SSParser<CF>> SSParser<CF> for SSOR<A, B> {
106 fn ss_parse<'a>(&self, it: &PIter<'a>, res: &mut String, cf: &CF) -> SSRes<'a> {
107 let pos = res.len();
108 match self.0.ss_parse(it, res, cf) {
109 Ok((r, e)) => Ok((r, e)),
110 Err(e) if e.is_break => Err(e),
111 Err(e) => {
112 cf.back(pos);
113 res.truncate(pos);
114 match self.1.ss_parse(it, res, cf) {
115 Ok((r, ex)) => Ok((r, ex)),
116 Err(e2) if e2.is_break => Err(e2),
117 Err(e2) => Err(e.longer(e2)),
118 }
119 }
120 }
121 }
122}
123
124pub struct SSDebug(pub &'static str);
125
126impl<CF: BackTo> SSParser<CF> for SSDebug {
127 fn ss_parse<'a>(&self, it: &PIter<'a>, _: &mut String, _: &CF) -> SSRes<'a> {
128 let (l, c) = it.lc();
129 println!("SS DEBUG (l{},c{}): {}, ", l, c, self.0);
130 Ok((it.clone(), None))
131 }
132}