Skip to content

Commit

Permalink
Keep only used GitHub enums and use default values for unused ones
Browse files Browse the repository at this point in the history
Use tip from documentation:
https://serde.rs/attr-default.html

This tip has been given by @dtolnay in this issue:
serde-rs/serde#1353
  • Loading branch information
nicokosi committed Aug 12, 2018
1 parent a43adc0 commit 886d2fa
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 47 deletions.
95 changes: 54 additions & 41 deletions src/github_events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ extern crate serde_json;
use self::reqwest::StatusCode;
use chrono::{DateTime, Utc};
use regex::Regex;
use serde::{Deserialize, Deserializer};
use std::io::{Error, ErrorKind};
use std::str;

Expand Down Expand Up @@ -112,7 +113,9 @@ fn last_page_from_link_header(link_header: &str) -> Option<u32> {
pub struct RawEvent {
pub actor: Actor,
pub payload: Payload,
#[serde(rename = "type")]
#[serde(
rename = "type", deserialize_with = "deserialize_field_type", default = "Type::default"
)]
pub event_type: Type,
pub created_at: DateTime<Utc>,
}
Expand All @@ -124,7 +127,8 @@ pub struct Actor {

#[derive(Debug, Deserialize, Eq, PartialEq)]
pub struct Payload {
pub action: Option<Action>,
#[serde(deserialize_with = "deserialize_field_action", default = "Action::default")]
pub action: Action,
}

#[derive(Debug, Deserialize, Eq, PartialEq)]
Expand All @@ -134,52 +138,42 @@ pub enum Action {
#[allow(non_camel_case_types)]
closed,
#[allow(non_camel_case_types)]
edited,
#[allow(non_camel_case_types)]
opened,
#[allow(non_camel_case_types)]
started,
#[serde(skip_deserializing)]
Unknown,
}
impl Action {
fn default() -> Self {
Action::Unknown
}
}

fn deserialize_field_action<'de, D>(deserializer: D) -> Result<Action, D::Error>
where
D: Deserializer<'de>,
{
Ok(Action::deserialize(deserializer).unwrap_or(Action::Unknown))
}

#[derive(Debug, Deserialize, Eq, PartialEq)]
pub enum Type {
CommitCommentEvent,
CreateEvent,
DeleteEvent,
DeploymentEvent,
DeploymentStatusEvent,
DownloadEvent,
FollowEvent,
ForkEvent,
ForkApplyEvent,
GistEvent,
GollumEvent,
InstallationEvent,
InstallationRepositoriesEvent,
IssueCommentEvent,
IssuesEvent,
LabelEvent,
MarketplacePurchaseEvent,
MemberEvent,
MembershipEvent,
MilestoneEvent,
OrganizationEvent,
OrgBlockEvent,
PageBuildEvent,
ProjectCardEvent,
ProjectColumnEvent,
ProjectEvent,
PublicEvent,
PullRequestEvent,
PullRequestReviewEvent,
PullRequestReviewCommentEvent,
PushEvent,
ReleaseEvent,
RepositoryEvent,
StatusEvent,
TeamEvent,
TeamAddEvent,
WatchEvent,
#[serde(skip_deserializing)]
Unknown,
}
impl Type {
fn default() -> Self {
Type::Unknown
}
}

fn deserialize_field_type<'de, D>(deserializer: D) -> Result<Type, D::Error>
where
D: Deserializer<'de>,
{
Ok(Type::deserialize(deserializer).unwrap_or(Type::Unknown))
}

mod tests {
Expand All @@ -200,14 +194,33 @@ mod tests {
login: "alice".to_string(),
},
payload: Payload {
action: Some(Action::opened),
action: Action::opened,
},
event_type: Type::PullRequestEvent,
created_at: Utc.ymd(2016, 12, 1).and_hms(16, 26, 43),
}
);
}

#[test]
fn parse_github_event_with_unknown_enums() {
assert_eq!(
raw_github_events(include_str!(
"../../test/github_event_with_unknown_enums.json"
)).unwrap()[0],
RawEvent {
actor: Actor {
login: "alice".to_string(),
},
payload: Payload {
action: Action::Unknown,
},
event_type: Type::Unknown,
created_at: Utc.ymd(2016, 12, 1).and_hms(16, 26, 43),
}
);
}

#[test]
fn parse_real_github_events_from_nicokosi_pullpito() {
let events = raw_github_events(include_str!("../../test/pullpito_github_events.json"));
Expand Down
14 changes: 8 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use std::thread;
use structopt::StructOpt;

pub mod github_events;
extern crate serde;

#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct Config {
Expand Down Expand Up @@ -102,7 +103,8 @@ fn events_per_author(events: Vec<RawEvent>) -> HashMap<String, Vec<RawEvent>> {
|| e.event_type == Type::IssueCommentEvent
})
.fold(HashMap::new(), |mut acc, event: RawEvent| {
(*acc.entry(event.actor.login.clone())
(*acc
.entry(event.actor.login.clone())
.or_insert_with(Vec::new))
.push(event);
acc
Expand All @@ -116,7 +118,7 @@ fn printable(repo: &str, events_per_author: &HashMap<String, Vec<RawEvent>>) ->
let opened_pull_requests = events
.into_iter()
.filter(|e| {
e.event_type == Type::PullRequestEvent && e.payload.action == Some(Action::opened)
e.event_type == Type::PullRequestEvent && e.payload.action == Action::opened
})
.count();
if opened_pull_requests > 0 {
Expand All @@ -128,7 +130,7 @@ fn printable(repo: &str, events_per_author: &HashMap<String, Vec<RawEvent>>) ->
let commented_pull_requests = events
.into_iter()
.filter(|e| {
e.event_type == Type::IssueCommentEvent && e.payload.action == Some(Action::created)
e.event_type == Type::IssueCommentEvent && e.payload.action == Action::created
})
.count();
if commented_pull_requests > 0 {
Expand All @@ -140,7 +142,7 @@ fn printable(repo: &str, events_per_author: &HashMap<String, Vec<RawEvent>>) ->
let closed_pull_requests = events
.into_iter()
.filter(|e| {
e.event_type == Type::PullRequestEvent && e.payload.action == Some(Action::closed)
e.event_type == Type::PullRequestEvent && e.payload.action == Action::closed
})
.count();
if closed_pull_requests > 0 {
Expand Down Expand Up @@ -241,7 +243,7 @@ mod test {
login: "alice".to_string(),
},
payload: Payload {
action: Some(Action::opened),
action: Action::opened,
},
event_type: Type::PullRequestEvent,
created_at: Utc.ymd(2016, 12, 1).and_hms(16, 26, 43),
Expand All @@ -263,7 +265,7 @@ mod test {
login: "alice".to_string(),
},
payload: Payload {
action: Some(Action::opened),
action: Action::opened,
},
event_type: Type::PullRequestEvent,
created_at: Utc.ymd(2016, 12, 1).and_hms(16, 26, 43),
Expand Down
19 changes: 19 additions & 0 deletions test/github_event_with_unknown_enums.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[
{
"id": "1",
"type": "ThisTypeDoesNotExist",
"actor": {
"login": "alice",
"display_login": "Alice"
},
"repo": {
"id": 2,
"name": "softwarevidal/fake-repo"
},
"payload": {
"action": "ThisActionDoesNotExist"
},
"public": false,
"created_at": "2016-12-01T16:26:43Z"
}
]

0 comments on commit 886d2fa

Please sign in to comment.