uap_rust/
device.rs

1use yaml_rust::{Yaml};
2use yaml;
3use regex::{Regex, Captures};
4
5///`Device` contains the device information from the user agent.
6#[derive(Debug, PartialEq, Eq)]
7pub struct Device {
8    pub family: String,
9    pub brand: Option<String>,
10    pub model: Option<String>,
11    pub regex: Option<String>,
12}
13
14#[derive(Debug)]
15pub struct DeviceParser {
16    pub regex: Regex,
17    pub family: Option<String>,
18    pub brand: Option<String>,
19    pub model: Option<String>,
20}
21
22impl DeviceParser {
23    pub fn from_yaml(y: &Yaml) -> Option<DeviceParser> {
24        let regex_flag = yaml::string_from_map(y, "regex_flag");
25        yaml::string_from_map(y, "regex")
26            .map(|r| 
27                 if regex_flag.is_some() { 
28                     format!("(?i){}", r)
29                 }else{
30                     r
31                 }
32            )
33            .map(|r| r.replace(r"\-", r"-"))
34            .map(|r| r.replace(r"\ ", r" "))
35            .map(|r| r.replace(r"\/", r"/"))
36            .and_then(|r| Regex::new(&r[..]).ok())
37            .map(|r| DeviceParser {
38                regex: r,
39                family: yaml::string_from_map(y, "device_replacement"),
40                brand: yaml::string_from_map(y, "brand_replacement"),
41                model: yaml::string_from_map(y, "model_replacement"),
42            })
43    }
44    fn replace(captures: &Captures, s: String) -> String {
45        captures.iter().zip((0..captures.len()))
46            .fold(s, |a, (c, i)| a.replace(&format!("${}", i)[..], c.unwrap_or("")))
47            .trim().to_string()
48    }
49
50    pub fn parse(&self, agent: String) -> Option<Device> {
51        self.regex.captures(&agent[..]).map(|c| {
52            let family = self.family.clone()
53                .map(|f| DeviceParser::replace(&c, f))
54                .unwrap_or(c.at(1).unwrap_or("Other").to_string());
55            let brand = self.brand.clone()
56                .map(|f| DeviceParser::replace(&c, f))
57                .or(c.at(1).map(|s| s.to_string()));
58            let model = self.model.clone()
59                .map(|f| DeviceParser::replace(&c, f))
60                .or(c.at(1).map(|s| s.to_string()));
61            Device {
62                family: family,
63                brand: brand,
64                model: model,
65                regex: Some(format!("{}", self.regex)),
66            }
67        })
68    }
69}