1use regex::Regex;
2use scraper::Html;
3use scraper::Selector;
4use thiserror::Error;
5
6#[derive(Error, Debug)]
7pub enum Error {
8 #[error("request error")]
9 Request(#[from] reqwest::Error),
10 #[error("page not found")]
11 NotFound,
12 #[error("invalid username")]
13 InvalidUsername,
14 #[error("error from txts (error {error:?}, message {message:?})")]
15 TxtsError { error: String, message: String },
16 #[error("unknown error from txts")]
17 UnknownTxtsError,
18 #[error("error while parsing html")]
19 HtmlParse,
20 #[error("error while parsing url")]
21 UrlParse(#[from] url::ParseError),
22 #[error("secret not present in redirect url")]
23 SecretNotPresent,
24 #[error("error while parsing secret uuid")]
25 UuidParse(#[from] uuid::Error),
26}
27
28pub(crate) fn parse_error(html: &Html) -> Result<(), Error> {
29 let error = html
30 .select(&Selector::parse(".error-message").unwrap())
31 .next();
32
33 if error.is_some() {
34 let err_title = html
35 .select(&Selector::parse(".error-message :nth-child(1)").unwrap())
36 .next()
37 .ok_or(Error::HtmlParse)?
38 .text()
39 .find(|s| !s.trim().is_empty())
40 .ok_or(Error::HtmlParse)?;
41 let err_msg = html
42 .select(&Selector::parse(".error-message :nth-child(2)").unwrap())
43 .next()
44 .ok_or(Error::HtmlParse)?
45 .text()
46 .find(|s| !s.trim().is_empty())
47 .ok_or(Error::HtmlParse)?;
48
49 return Err(Error::TxtsError {
50 error: err_title.trim().to_string(),
51 message: err_msg.trim().to_string(),
52 });
53 }
54
55 Ok(())
56}
57
58pub(crate) fn check_username(username: &str) -> Result<(), Error> {
59 let re = Regex::new(r"^[A-Za-z0-9_.]{3,16}$").unwrap();
60 match re.is_match(username) {
61 true => Ok(()),
62 false => Err(Error::InvalidUsername),
63 }
64}