From c40aa2bf95131317e2a9b199afd0b34ae2d847ee Mon Sep 17 00:00:00 2001 From: iximeow Date: Fri, 27 Oct 2017 01:23:05 -0700 Subject: better error handling in cases where event json changes --- src/commands/twete.rs | 5 --- src/tw/events.rs | 122 ++++++++++++++++++++++++++++++++++++-------------- src/tw/mod.rs | 12 ++--- 3 files changed, 96 insertions(+), 43 deletions(-) diff --git a/src/commands/twete.rs b/src/commands/twete.rs index b0530c8..eb21a15 100644 --- a/src/commands/twete.rs +++ b/src/commands/twete.rs @@ -124,11 +124,6 @@ fn rep(line: String, tweeter: &mut tw::TwitterCache, queryer: &mut Queryer) { ats.remove_item(&rt_author_handle); ats.insert(1, rt_author_handle); } - if let Some(qt_tweet) = twete.quoted_tweet_id.and_then(|id| tweeter.retrieve_tweet(&TweetId::Twitter(id))).map(|x| x.clone()) { - // let qt_author_handle = tweeter.retrieve_user(&qt_tweet.author_id).unwrap().handle.to_owned(); - // ats.remove_item(&qt_author_handle); - // ats.insert(1, qt_author_handle); - } //let ats_vec: Vec<&str> = ats.into_iter().collect(); //let full_reply = format!("{} {}", ats_vec.join(" "), reply); let decorated_ats: Vec = ats.into_iter().map(|x| format!("@{}", x)).collect(); diff --git a/src/tw/events.rs b/src/tw/events.rs index afc7fbb..35167a3 100644 --- a/src/tw/events.rs +++ b/src/tw/events.rs @@ -13,39 +13,95 @@ pub enum Event { } impl Event { - pub fn from_json(structure: serde_json::Map) -> Option { - match &structure["event"].as_str().unwrap() { - &"follow" => Some(Event::Followed { - user_id: structure["source"]["id_str"].as_str().unwrap().to_owned() - }), - &"unfollow" => Some(Event::Unfollowed { - user_id: structure["source"]["id_str"].as_str().unwrap().to_owned() - }), - &"favorite" => Some(Event::Fav { - user_id: structure["source"]["id_str"].as_str().unwrap().to_owned(), - twete_id: structure["target_object"]["id_str"].as_str().unwrap().to_owned() - }), - &"unfavorite" => Some(Event::Unfav { - user_id: structure["source"]["id_str"].as_str().unwrap().to_owned(), - twete_id: structure["target_object"]["id_str"].as_str().unwrap().to_owned() - }), - &"favorited_retweet" => Some(Event::Fav_RT { - user_id: structure["source"]["id_str"].as_str().unwrap().to_owned(), - twete_id: structure["target_object"]["id_str"].as_str().unwrap().to_owned() - }), - &"retweeted_retweet" => Some(Event::RT_RT { - user_id: structure["source"]["id_str"].as_str().unwrap().to_owned(), - twete_id: structure["target_object"]["id_str"].as_str().unwrap().to_owned() - }), - &"quoted_tweet" => Some(Event::Quoted { - user_id: structure["source"]["id_str"].as_str().unwrap().to_owned(), - twete_id: structure["target_object"]["id_str"].as_str().unwrap().to_owned() - }), -// &"list_member_added" => -// what about removed? -// &"blocked" => Blocked { }, -// &"unblocked" => Unblocked { }, - e => { println!("unrecognized event: {}", e); None } + fn get_source_id(structure: serde_json::Map) -> Result { + match structure.get("source").and_then(|x| x.get("id_str").and_then(|x| x.as_str())) { + Some(id) => Ok(id.to_string()), + None => Err("No id_str string at .source.id_str".to_string()) + } + } + fn get_source_target_ids(structure: serde_json::Map) -> Result<(String, String), String> { + match ( + structure.get("source").and_then(|x| x.get("id_str").and_then(|x| x.as_str())), + structure.get("target_obj").and_then(|x| x.get("id_str").and_then(|x| x.as_str())) + ) { + (Some(source_id), Some(target_id)) => Ok((source_id.to_string(), target_id.to_string())), + (None, Some(target_id)) => Err("No id_str string at .source.id_str".to_string()), + (Some(target_id), None) => Err("No id_str string at .target_object.id_str".to_string()), + (None, None) => Err("No id_str at source or target_object".to_string()) + } + } + // maybe type error + // better? string is ok + // for now.. + pub fn from_json(structure: serde_json::Map) -> Result { + match structure.get("event").and_then(|x| x.as_str()).map(|x| x.to_owned()) { + Some(event) => { + let event_ref: &str = &event; + match event_ref { + "follow" => + Event::get_source_id(structure) + .map(|id_str| + Event::Followed { + user_id: id_str + } + ), + "unfollow" => + Event::get_source_id(structure) + .map(|id_str| + Event::Unfollowed { + user_id: id_str + } + ), + "favorite" => + Event::get_source_target_ids(structure) + .map(|(source_id, target_id)| + Event::Fav { + user_id: source_id, + twete_id: target_id + } + ), + "unfavorite" => + Event::get_source_target_ids(structure) + .map(|(source_id, target_id)| + Event::Unfav { + user_id: source_id, + twete_id: target_id + } + ), + "favorited_retweet" => + Event::get_source_target_ids(structure) + .map(|(source_id, target_id)| + Event::Fav_RT { + user_id: source_id, + twete_id: target_id + } + ), + "retweeted_retweet" => + Event::get_source_target_ids(structure) + .map(|(source_id, target_id)| + Event::RT_RT { + user_id: source_id, + twete_id: target_id + } + ), + "quoted_tweet" => + Event::get_source_target_ids(structure) + .map(|(source_id, target_id)| + Event::Quoted { + user_id: source_id, + twete_id: target_id + } + ), + // "list_member_added" => + // what about removed? + // "blocked" => Blocked { }, + // "unblocked" => Unblocked { }, + e => { println!("unrecognized event: {}", e); Err(e.to_string()) } + } + }, + None => { + Err("No event in event json...".to_string()) + } } } } diff --git a/src/tw/mod.rs b/src/tw/mod.rs index 5f40c5e..d0bad59 100644 --- a/src/tw/mod.rs +++ b/src/tw/mod.rs @@ -257,7 +257,6 @@ fn parse_word_command<'a, 'b>(line: &'b str, commands: &[&'a Command]) -> Option } } else if line.starts_with(cmd.keyword) { if line.find(" ").map(|x| x == cmd.keyword.len()).unwrap_or(false) { - // let inner_twid = u64::from_str(&linestr.split(" ").collect::>()[1]).unwrap(); return Some((line.get((cmd.keyword.len() + 1)..).unwrap().trim(), &cmd)); } } @@ -641,10 +640,13 @@ fn handle_twitter_event( tweeter: &mut TwitterCache, mut queryer: &mut ::Queryer) { tweeter.cache_api_event(structure.clone(), &mut queryer); - if let Some(event) = events::Event::from_json(structure) { - tweeter.display_info.recv(display::Infos::Event(event)); - } else { - // ought to handle the None case... + match events::Event::from_json(structure) { + Ok(event) => { + tweeter.display_info.recv(display::Infos::Event(event)); + }, + Err(e) => { + tweeter.display_info.status(format!("Unknown twitter json: {:?}", e)); + } } } -- cgit v1.1