1use chrono::NaiveDate;
2use indexmap::IndexMap;
3use serde_derive::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6#[derive(Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
7pub struct ScreenNameResult {
8 pub accounts: Vec<Account>,
9}
10
11impl ScreenNameResult {
12 pub fn includes_screen_name(&self, screen_name: &str) -> bool {
13 let target_screen_name = screen_name.to_lowercase();
14 self.accounts.iter().any(|account| {
15 account
16 .screen_names
17 .keys()
18 .any(|screen_name| screen_name.to_lowercase() == target_screen_name)
19 })
20 }
21}
22
23#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)]
24pub struct Account {
25 pub id: u64,
26 #[serde(rename = "screen_names")]
27 pub screen_names: IndexMap<String, Option<Vec<NaiveDate>>>,
28}
29
30impl Account {
31 pub fn from_raw_result(id: u64, result: HashMap<String, Vec<NaiveDate>>) -> Self {
32 let mut sorted = result
33 .into_iter()
34 .map(|(screen_name, mut dates)| {
35 dates.sort();
36
37 let value = match dates.len() {
38 0 => None,
39 1 => Some(vec![dates[0]]),
40 n => Some(vec![dates[0], dates[n - 1]]),
41 };
42
43 (screen_name, value)
44 })
45 .collect::<IndexMap<_, _>>();
46
47 sorted.sort_by(|screen_name_a, dates_a, screen_name_b, dates_b| {
48 dates_a
49 .as_ref()
50 .and_then(|dates| dates.get(0))
51 .cmp(&dates_b.as_ref().and_then(|dates| dates.get(0)))
52 .then_with(|| screen_name_a.cmp(screen_name_b))
53 });
54
55 Self {
56 id,
57 screen_names: sorted,
58 }
59 }
60}