github_email/authors/
mod.rs1use std::{
2 collections::BTreeMap,
3 fmt::{Debug, Display, Formatter},
4 iter::Rev,
5 vec::IntoIter,
6};
7
8use itertools::Itertools;
9use serde::{Deserialize, Serialize};
10use url::Url;
11
12use crate::{collect_repo_events, collect_user_events, Result};
13
14pub mod query;
15
16#[derive(Default, Serialize, Deserialize)]
17pub struct Authors {
18 inner: BTreeMap<String, CommitAuthor>,
19}
20
21#[derive(Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
22pub enum AuthorQuery {
23 Nothing,
24 User(String),
25 Repo(String, String),
26}
27
28#[derive(Clone, Debug, Serialize, Deserialize)]
29pub struct CommitAuthor {
30 pub name: String,
31 pub email: String,
32 pub count: usize,
33}
34
35impl Authors {
36 pub fn clear(&mut self) {
37 self.inner.clear()
38 }
39 pub fn get(&self, name: &str) -> Option<&CommitAuthor> {
40 self.inner.get(name)
41 }
42 pub fn insert(&mut self, author: CommitAuthor) {
43 match self.inner.get_mut(&author.name) {
44 Some(s) => s.count += author.count,
45 None => self.insert_force(author),
46 }
47 }
48 pub fn insert_force(&mut self, author: CommitAuthor) {
49 self.inner.insert(author.name.clone(), author);
50 }
51 pub fn items(&self) -> Vec<CommitAuthor> {
52 self.into_iter().cloned().collect()
53 }
54 pub fn count_commits(&self) -> usize {
55 self.inner.iter().map(|v| v.1.count).sum()
56 }
57}
58
59impl Debug for Authors {
60 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
61 f.debug_list().entries(self.items().iter()).finish()
62 }
63}
64impl Display for Authors {
65 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
66 f.debug_list().entries(self.items().iter()).finish()
67 }
68}
69
70impl<'i> IntoIterator for &'i Authors {
71 type Item = &'i CommitAuthor;
72 type IntoIter = Rev<IntoIter<&'i CommitAuthor>>;
73
74 fn into_iter(self) -> Self::IntoIter {
75 self.inner.values().sorted_by_key(|v| v.count).rev()
76 }
77}