1extern crate serde;
9extern crate serde_xml_rs;
10
11extern crate regex;
12extern crate hex;
13extern crate base64;
14
15use std::error::Error;
16
17use regex::Regex;
18use serde::Deserialize;
19
20#[derive(Deserialize)]
21struct Response {
22 accounts: Accounts,
23}
24
25#[derive(Deserialize)]
26struct Accounts {
27 accts_version: u8,
28 cbc: bool,
29 #[serde(rename = "$value")]
30 accounts: Vec<Account>,
31}
32
33#[derive(Deserialize, Clone)]
34pub struct Account {
35 pub url: String,
36 pub login: Login,
37}
38
39#[derive(Deserialize, Clone)]
40pub struct Login {
41 #[serde(skip)]
42 pub cbc: bool,
43 #[serde(rename = "u")]
44 pub username: String,
45 #[serde(rename = "p")]
46 pub password: String,
47}
48
49#[derive(Clone)]
51pub struct Results {
52 pub version: u8,
53 pub acct_cbc: bool,
54 pub accounts: Vec<Account>,
55}
56impl TryFrom<&str> for Results {
57 type Error = Box<dyn Error>;
58 fn try_from(value: &str) -> Result<Self, Self::Error> {
59 let data: Response = serde_xml_rs::from_str(value).unwrap();
60
61 let version = data.accounts.accts_version;
62 let acct_cbc = data.accounts.cbc;
63 let accounts = data.accounts.accounts.iter().map(|x| {
64 let url = core::str::from_utf8(hex::decode(x.url.clone()).unwrap().as_slice()).unwrap().to_string();
65 let cbc = Regex::new("^![^|]*|.*$").unwrap().is_match(x.login.password.clone().as_str());
66 let login = Login {
67 cbc,
68 ..x.login.clone()
69 };
70
71 Account { url, login }
72 }).collect::<Vec<Account>>();
73
74 Ok(Self {
75 version,
76 acct_cbc,
77 accounts,
78 })
79 }
80}
81