1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use chrono::prelude::*;
use chrono::DateTime;
use std::borrow::Cow;
use std::collections::HashSet;
use std::iter::FromIterator;

use codealong::{AnalyzedDiff, Event, Person};

use crate::pull_request::PullRequest;

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AnalyzedPullRequest {
    timestamp: DateTime<Utc>,

    normalized_author: Person,

    #[serde(flatten)]
    pr: PullRequest,

    #[serde(flatten)]
    pub diff: Option<AnalyzedDiff>,

    pub time_to_resolve: Option<i64>,
}

impl AnalyzedPullRequest {
    pub fn new(
        pr: PullRequest,
        diff: Option<AnalyzedDiff>,
        normalized_author: Person,
    ) -> AnalyzedPullRequest {
        AnalyzedPullRequest {
            timestamp: pr.merged_at.unwrap_or(pr.updated_at),
            normalized_author,
            diff,
            time_to_resolve: pr
                .merged_at
                .as_ref()
                .map(|ma| (ma.clone() - pr.created_at.clone()).num_seconds()),
            pr,
        }
    }
}

impl Event for AnalyzedPullRequest {
    fn timestamp(&self) -> &DateTime<Utc> {
        &self.timestamp
    }

    fn id(&self) -> Cow<str> {
        self.pr.id.to_string().into()
    }

    fn event_type(&self) -> &str {
        "pull_request"
    }

    fn tags(&self) -> HashSet<String> {
        if let Some(ref diff) = self.diff {
            HashSet::from_iter(diff.tag_stats.keys().map(|s| s.to_owned()))
        } else {
            HashSet::new()
        }
    }
}