shio/router/
parameters.rs1use std::ops::Index;
2use std::sync::Arc;
3use std::collections::HashMap;
4
5use util::typemap::Key;
6use regex::Captures;
7
8pub struct Parameters {
9 text: String,
10 matches: Vec<Option<(usize, usize)>>,
11 names: Arc<HashMap<String, usize>>,
12}
13
14impl Parameters {
15 pub(crate) fn new(names: Arc<HashMap<String, usize>>, text: &str, captures: Captures) -> Self {
16 Self {
17 names,
18 text: text.into(),
19 matches: captures
20 .iter()
21 .map(|capture| capture.map(|m| (m.start(), m.end())))
22 .collect(),
23 }
24 }
25
26 pub fn get(&self, index: usize) -> Option<&str> {
27 self.matches
28 .get(index + 1)
31 .and_then(|m| m.map(|(start, end)| &self.text[start..end]))
32 }
33
34 pub fn name(&self, name: &str) -> Option<&str> {
35 self.names.get(name).and_then(|&i| self.get(i - 1))
36 }
37}
38
39impl Key for Parameters {
40 type Value = Self;
41}
42
43impl Index<usize> for Parameters {
44 type Output = str;
45
46 fn index(&self, index: usize) -> &Self::Output {
52 self.get(index)
53 .unwrap_or_else(|| panic!("no parameter at index '{}'", index))
54 }
55}
56
57impl<'b> Index<&'b str> for Parameters {
58 type Output = str;
59
60 fn index<'a>(&'a self, name: &str) -> &'a str {
66 self.name(name)
67 .unwrap_or_else(|| panic!("no parameter named '{}'", name))
68 }
69}