github_email/authors/
query.rs1use crate::{parse_queries, GithubError};
2
3use super::*;
4
5impl Authors {
6 pub async fn query<Q>(&mut self, query: Q) -> Result<()>
7 where
8 Q: Into<AuthorQuery>,
9 {
10 match query.into() {
11 AuthorQuery::Nothing => {}
12 AuthorQuery::User(user) => collect_user_events(&user, self).await?,
13 AuthorQuery::Repo(user, repo) => collect_repo_events(&user, &repo, self).await?,
14 }
15 Ok(())
16 }
17 pub async fn query_many(&mut self, queries: &str) -> Vec<GithubError> {
18 let mut errors = vec![];
19 for query in parse_queries(queries) {
20 if let Err(e) = self.query(query).await {
22 errors.push(e)
23 }
24 }
25 errors
26 }
27}
28
29impl AuthorQuery {
30 pub fn is_none(&self) -> bool {
31 matches!(self, AuthorQuery::Nothing)
32 }
33 pub fn is_some(&self) -> bool {
34 !self.is_none()
35 }
36}
37
38impl From<&str> for AuthorQuery {
39 fn from(value: &str) -> Self {
40 let url = match value.contains("://") {
41 true => value.to_string(),
42 false => format!("https://github.com/{value}"),
43 };
44 match Url::parse(&url) {
45 Ok(o) => AuthorQuery::from(&o),
46 Err(_) => AuthorQuery::Nothing,
47 }
48 }
49}
50
51impl From<&Url> for AuthorQuery {
52 fn from(value: &Url) -> Self {
53 let path = value.path().split("/").collect::<Vec<_>>();
54 match path_slice(&path) {
56 [user] => AuthorQuery::User(user.to_string()),
57 [user, repo, ..] => AuthorQuery::Repo(user.to_string(), repo.to_string()),
58 _ => AuthorQuery::Nothing,
59 }
60 }
61}
62
63fn path_slice<'v, 's>(path: &'v [&'s str]) -> &'v [&'s str] {
64 let mut l = 0;
65 let mut r = path.len();
66 for ls in path {
67 match ls.is_empty() {
68 true => l += 1,
69 false => break,
70 }
71 }
72 for rs in path.iter().rev() {
73 match rs.is_empty() {
74 true => r -= 1,
75 false => break,
76 }
77 }
78 if l > r { &[] } else { &path[l..r] }
80}