1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use crate::ctx::Context;
use crate::ctx::Match;
use crate::ctx::Span;
use crate::err::Error;
use crate::iter::IndexBySpan;
use crate::iter::IteratorBySpan;
use crate::iter::SpanIterator;
use crate::re::Regex;

#[derive(Debug, Clone, Default)]
pub struct SimpleStorer {
    spans: Vec<Vec<Span>>,
}

impl SimpleStorer {
    pub fn new(capacity: usize) -> Self {
        Self {
            spans: vec![vec![]; capacity],
        }
    }

    pub fn new_with(spans: Vec<Vec<Span>>) -> Self {
        Self { spans }
    }

    pub fn with_capacity(mut self, capacity: usize) -> Self {
        self.spans = vec![vec![]; capacity];
        self
    }

    pub fn len(&self) -> usize {
        self.spans.len()
    }

    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    pub fn reset(&mut self) -> &mut Self {
        self.spans.iter_mut().for_each(|v| v.clear());
        self
    }
}

impl SimpleStorer {
    pub fn contain(&self, id: usize) -> bool {
        self.spans.get(id).map(|v| !v.is_empty()).unwrap_or(false)
    }

    pub fn add_span(&mut self, id: usize, span: Span) -> &mut Self {
        self.spans[id].push(span);
        self
    }

    pub fn clr_span(&mut self, id: usize) -> &mut Self {
        if let Some(v) = self.spans.get_mut(id) {
            v.clear()
        };
        self
    }

    pub fn span(&self, id: usize, index: usize) -> Option<&Span> {
        self.spans.get(id).and_then(|v| v.get(index))
    }

    pub fn spans(&self, id: usize) -> Option<&Vec<Span>> {
        self.spans
            .get(id)
            .and_then(|v| if v.is_empty() { None } else { Some(v) })
    }

    pub fn spans_iter(&self, id: usize) -> Option<SpanIterator<'_>> {
        self.spans(id).map(SpanIterator::new)
    }
}

impl SimpleStorer {
    pub fn slice<'a, T>(
        &self,
        value: &'a T,
        id: usize,
        index: usize,
    ) -> Option<&'a <T as IndexBySpan>::Output>
    where
        T: IndexBySpan + ?Sized,
    {
        let span = self.span(id, index)?;

        value.get_by_span(span)
    }

    pub fn slice_iter<'a, T>(&self, str: &'a T, id: usize) -> Option<IteratorBySpan<'a, '_, T>>
    where
        T: IndexBySpan + ?Sized,
    {
        Some(IteratorBySpan::new(str, self.spans(id)?))
    }
}

impl SimpleStorer {
    pub fn try_cap<'a, C, P: Regex<C, Ret = Span>>(
        &mut self,
        id: usize,
        ctx: &mut C,
        pat: &P,
    ) -> Result<P::Ret, Error>
    where
        C: Context<'a> + Match<C>,
    {
        let ret = ctx.try_mat(pat)?;

        self.add_span(id, ret);
        Ok(ret)
    }
}