1use std::io::prelude::*;
2use std::fs::{File};
3use yaml_rust::{YamlLoader};
4
5use client::{Client};
6use ua::{UserAgent, UserAgentParser};
7use device::{Device, DeviceParser};
8use os::{OS, OSParser};
9use result::*;
10use yaml;
11
12#[derive(Debug)]
14pub struct Parser {
15 pub ua_regex: Vec<UserAgentParser>,
16 pub devices_regex: Vec<DeviceParser>,
17 pub os_regex: Vec<OSParser>,
18}
19
20impl Parser {
21
22 pub fn from_file(regexes_file: &str) -> Result<Parser> {
27 let mut file = try!(File::open(regexes_file));
28 let mut yaml = String::new();
29 let _ = file.read_to_string(&mut yaml);
30 Parser::from_str(&yaml)
31 }
32
33 pub fn from_str(s: &str) -> Result<Parser> {
38 let docs = try!(YamlLoader::load_from_str(&s));
40 let p = Parser {
41 devices_regex: yaml::from_map(&docs[0],"device_parsers")
42 .map(|y| yaml::filter_map_over_arr(y, DeviceParser::from_yaml)).unwrap(),
43 ua_regex: yaml::from_map(&docs[0],"user_agent_parsers")
44 .map(|y| yaml::filter_map_over_arr(y, UserAgentParser::from_yaml)).unwrap(),
45 os_regex: yaml::from_map(&docs[0],"os_parsers")
46 .map(|y| yaml::filter_map_over_arr(y, OSParser::from_yaml)).unwrap(),
47 };
48 Ok(p)
49 }
50
51 pub fn new() -> Result<Parser> {
56 let s = include_str!("uap-core/regexes.yaml");
57 Parser::from_str(&s)
58 }
59
60 pub fn parse(&self, agent: String) -> Client {
62 let ua = self.ua_regex.iter().filter_map(|u| u.parse(agent.clone())).next();
66 let u = ua.unwrap_or(
67 UserAgent {
68 family: "Other".to_string(),
69 major: None,
70 minor: None,
71 patch: None,
72 });
73 let dev = self.devices_regex.iter().filter_map(|d| d.parse(agent.clone())).next();
74 let d = dev.unwrap_or(Device {
75 family: "Other".to_string(),
76 model: None,
77 brand: None,
78 regex: None,
79 });
80 let oss = self.os_regex.iter().filter_map(|d| d.parse(agent.clone())).next();
81 let o = oss.unwrap_or(OS {
82 family: "Other".to_string(),
83 major: None,
84 minor: None,
85 patch: None,
86 patch_minor: None,
87 });
88 Client {
89 user_agent: u,
90 os: o,
91 device: d,
92 }
93 }
94}