Skip to content

Commit

Permalink
Fix #22: Fix 'unknown variant' failures
Browse files Browse the repository at this point in the history
Only keep used GitHub enums and set a default value for unused ones.

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 0abb031
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 0abb031

Please sign in to comment.