reproto_core/
attributes.rs

1//! Provide a collection of attributes and a convenient way for querying them.
2//!
3//! These structures are all map-like.
4
5use std::borrow::Borrow;
6use std::collections::HashMap;
7use std::hash::Hash;
8use std::mem;
9use std::vec;
10use {Loc, RpValue, Span};
11
12/// Iterator over unused positions.
13pub struct Unused {
14    iter: vec::IntoIter<Span>,
15}
16
17impl Iterator for Unused {
18    type Item = Span;
19
20    fn next(&mut self) -> Option<Self::Item> {
21        self.iter.next()
22    }
23}
24
25#[derive(Debug, Clone, Serialize)]
26pub struct Selection {
27    /// Storing words and their locations.
28    words: Vec<Loc<RpValue>>,
29    /// Storing values and their locations.
30    values: HashMap<String, (Loc<String>, Loc<RpValue>)>,
31}
32
33impl Selection {
34    pub fn new(
35        words: Vec<Loc<RpValue>>,
36        values: HashMap<String, (Loc<String>, Loc<RpValue>)>,
37    ) -> Selection {
38        Selection {
39            words: words,
40            values: values,
41        }
42    }
43
44    /// Take the given value, removing it in the process.
45    pub fn take<Q: ?Sized>(&mut self, key: &Q) -> Option<Loc<RpValue>>
46    where
47        String: Borrow<Q>,
48        Q: Hash + Eq,
49    {
50        self.values.remove(key).map(|v| v.1)
51    }
52
53    /// Take the given value, removing it in the process.
54    pub fn take_words(&mut self) -> Vec<Loc<RpValue>> {
55        mem::replace(&mut self.words, vec![])
56    }
57
58    /// Take a single word.
59    pub fn take_word(&mut self) -> Option<Loc<RpValue>> {
60        self.words.pop()
61    }
62
63    /// Get an iterator over unused positions.
64    pub fn unused(&self) -> Unused {
65        let mut positions = Vec::new();
66        positions.extend(self.words.iter().map(|v| Loc::span(v)));
67        positions.extend(self.values.values().map(|v| Loc::span(&v.0)));
68        Unused {
69            iter: positions.into_iter(),
70        }
71    }
72}
73
74#[derive(Debug, Clone, Serialize)]
75pub struct Attributes {
76    words: HashMap<String, Span>,
77    selections: HashMap<String, Loc<Selection>>,
78}
79
80impl Attributes {
81    pub fn new(
82        words: HashMap<String, Span>,
83        selections: HashMap<String, Loc<Selection>>,
84    ) -> Attributes {
85        Attributes {
86            words: words,
87            selections: selections,
88        }
89    }
90
91    /// Take the given selection, removing it in the process.
92    pub fn take_word<Q: ?Sized>(&mut self, key: &Q) -> bool
93    where
94        String: Borrow<Q>,
95        Q: Hash + Eq,
96    {
97        self.words.remove(key).is_some()
98    }
99
100    /// Take the given selection, removing it in the process.
101    pub fn take_selection<Q: ?Sized>(&mut self, key: &Q) -> Option<Loc<Selection>>
102    where
103        String: Borrow<Q>,
104        Q: Hash + Eq,
105    {
106        self.selections.remove(key)
107    }
108
109    /// Get an iterator over unused positions.
110    pub fn unused(&self) -> Unused {
111        let mut positions = Vec::new();
112        positions.extend(self.words.values());
113        positions.extend(self.selections.values().map(Loc::span));
114        Unused {
115            iter: positions.into_iter(),
116        }
117    }
118}