hltv/converter/
player.rs

1use crate::data::*;
2use crate::ConvertCollection;
3use crate::{Error, Error::ConversionError};
4
5use crate::tl_extensions::*;
6
7impl ConvertCollection for Player {
8    fn convert<'a>(d: &'a tl::VDom<'a>) -> Result<Vec<Player>, Error> {
9        let mut result = Vec::<Player>::new();
10        // query selector for match page
11        for_teampage(d, &mut result)?;
12        // query selector for team page
13        for_matchpage(d, &mut result)?;
14
15        Ok(result)
16    }
17}
18
19/// Parses the DOM according to the schema found on the match page.
20fn for_matchpage(d: &tl::VDom, r: &mut Vec<Player>) -> Result<(), Error> {
21    let selector = d.query_selector("td.player").unwrap();
22    for x in selector {
23        let node = x.to_rich(d);
24        let id: u32 = match node.find("flagAlign").get_attr("data-player-id")? {
25            Some(x) => x,
26            None => return Err(ConversionError("No ID found for player")),
27        };
28        let nickname = node
29            .find("text-ellipsis")
30            .inner_text()
31            .ok_or(ConversionError("No player name found"))?;
32        r.push(Player { id, nickname });
33    }
34    Ok(())
35}
36
37/// Parses the DOM according to the schema found on the team page.
38fn for_teampage(d: &tl::VDom, r: &mut Vec<Player>) -> Result<(), Error> {
39    let mut selector = d.query_selector("div.bodyshot-team-bg").unwrap();
40    let parent = selector.next();
41    if parent.is_none() {
42        return Ok(());
43    }
44    for node in d.select_nodes(parent.unwrap(), "col-custom") {
45        let tag = node.get(d.parser()).unwrap().as_tag().unwrap();
46
47        let name: String = match tag.get_attr_str("title") {
48            Some(x) => x,
49            None => return Err(ConversionError("missing title attribute in player div")),
50        };
51
52        let id: String = match tag.get_attr_str("href") {
53            Some(x) => x,
54            None => return Err(ConversionError("missing href link in player div")),
55        };
56
57        let id = id.split('/').nth(2).ok_or(Error::ParseError)?;
58       
59        let p = Player {
60            id: match id.parse() {
61                Ok(id) => id,
62                _ => return Err(ConversionError("incorrect ID / format of href was changed")),
63            },
64            nickname: name,
65        };
66        r.push(p);
67    }
68    Ok(())
69}
70
71#[cfg(test)]
72mod tests {
73    use super::*;
74
75    /// Tests if the converter parses player info from a match page correctly.
76    #[test]
77    pub fn player_match() {
78        let input = include_str!("../testdata/player_match.html");
79        let dom = tl::parse(input, tl::ParserOptions::default()).unwrap();
80        let result = Player::convert(&dom).unwrap();
81        assert_eq!(result.len(), 2);
82        assert_eq!(
83            result[0],
84            Player {
85                id: 1337,
86                nickname: "dist1ll".to_string()
87            }
88        );
89        assert_eq!(
90            result[1],
91            Player {
92                id: 1338,
93                nickname: "3rr0r".to_string()
94            }
95        );
96    }
97
98    /// Tests if the converter parses player info from a team page correctly.
99    #[test]
100    pub fn player_team() {
101        let input = include_str!("../testdata/player_team.html");
102        let dom = tl::parse(input, tl::ParserOptions::default()).unwrap();
103        let result = Player::convert(&dom).unwrap();
104        assert_eq!(result.len(), 3);
105        assert_eq!(
106            result[0],
107            Player {
108                id: 123,
109                nickname: "dist1ll".to_string()
110            }
111        );
112        assert_eq!(
113            result[1],
114            Player {
115                id: 124,
116                nickname: "3rr0r".to_string()
117            }
118        );
119        assert_eq!(
120            result[2],
121            Player {
122                id: 125,
123                nickname: "rabbit".to_string()
124            }
125        );
126    }
127}