From a48e275f387760425a3207292591e9f4c21a366d Mon Sep 17 00:00:00 2001 From: Douman Date: Mon, 30 Oct 2017 10:40:01 +0300 Subject: [PATCH] 0.2.0: Join futures instead of running it separately --- Cargo.toml | 2 +- README.md | 6 ++++-- src/api/gab.rs | 25 ++++++++++++++++++------- src/api/twitter.rs | 17 +++++++++++++---- src/main.rs | 33 +++++++++++++++++++++------------ src/utils.rs | 6 +++++- 6 files changed, 62 insertions(+), 27 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 15e89ec..595d62e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fie" -version = "0.1.0" +version = "0.2.0" authors = ["Douman "] repository = "https://github.com/DoumanAsh/fie" description = "Small and cute twitter app." diff --git a/README.md b/README.md index b6eee7a..9653f1c 100644 --- a/README.md +++ b/README.md @@ -21,16 +21,18 @@ Use [example](fie.toml) as reference. ## Usage ``` -fie 0.1.0 +fie 0.2.0 Douman Small and cute twitter app. USAGE: - fie.exe [SUBCOMMAND] + fie.exe [FLAGS] [SUBCOMMAND] FLAGS: + --gab Use gab.ai. By default all social medias are used unless flag is specified. -h, --help Prints help information + --twitter Use Twitter. By default all social medias are used unless flag is specified. -V, --version Prints version information SUBCOMMANDS: diff --git a/src/api/gab.rs b/src/api/gab.rs index 9d04b62..b3ecc7c 100644 --- a/src/api/gab.rs +++ b/src/api/gab.rs @@ -4,7 +4,7 @@ mod hyper { pub use ::hyper::client::{HttpConnector, FutureResponse}; pub use ::hyper_tls::{HttpsConnector}; } - +use ::futures::future; use ::hyper::mime; use ::serde_json; @@ -14,7 +14,10 @@ use ::tokio_core::reactor::{ use super::common; use ::config; -use ::utils::Image; +use ::utils::{ + empty_future_job, + Image +}; const POST_URL: &'static str = "https://gab.ai/posts"; const IMAGES_URL: &'static str = "https://gab.ai/api/media-attachments/images"; @@ -137,12 +140,20 @@ impl Client { self.hyper.request(req) } - pub fn handle_post(response: hyper::Response) -> Result<(), String> { - if response.status() != hyper::StatusCode::Ok { - return Err(format!("Failed to post. Status: {}", response.status())); + pub fn handle_post(result: Result) -> future::FutureResult<(), ()> { + println!(">>>Gab:"); + match result { + Ok(response) => { + if response.status() != hyper::StatusCode::Ok { + println!("Failed to post. Status: {}", response.status()); + } + else { + println!("OK"); + } + } + Err(error) => println!("{}", error) } - println!("OK"); - Ok(()) + empty_future_job() } } diff --git a/src/api/twitter.rs b/src/api/twitter.rs index 76e84df..35719b6 100644 --- a/src/api/twitter.rs +++ b/src/api/twitter.rs @@ -7,7 +7,7 @@ use ::egg_mode::{ tweet, media }; - +use ::futures::future; use ::tokio_core::reactor::{ Handle }; @@ -15,7 +15,10 @@ use ::tokio_core::reactor::{ use super::common; use ::config; -use ::utils::Image; +use ::utils::{ + empty_future_job, + Image +}; ///Twitter client. pub struct Client { @@ -58,7 +61,13 @@ impl Client { tweet::DraftTweet::new(&message).media_ids(images).send(&self.token, &self.handle) } - pub fn handle_post(response: Response) -> Result<(), String> { - Ok(println!("OK(id={})", response.response.id)) + pub fn handle_post(result: Result, String>) -> future::FutureResult<(), ()> { + println!(">>>Twitter:"); + match result { + Ok(rsp) => println!("OK(id={})", rsp.response.id), + Err(error) => println!("{}", error) + } + + empty_future_job() } } diff --git a/src/main.rs b/src/main.rs index a89dd0f..b28719b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,36 +33,45 @@ fn run() -> Result { match args.command { cli::Commands::Post(message, tags, None) => { + //TODO: Find a better way to schedule futures. + //Boxing requires allocations and dynamic dispatch after all. + //But using Handle::spawn() has restrictions on lifetimes which needs to be worked out + //somehow + let mut jobs: Vec>> = vec![]; if args.flags.gab { - println!(">>>Gab:"); - tokio_core.run(gab.post(&message, &tags).map_err(error_formatter!("Cannot post.")).and_then(api::gab::Client::handle_post))?; + let gab_post = gab.post(&message, &tags).map_err(error_formatter!("Cannot post.")).then(api::gab::Client::handle_post); + jobs.push(Box::new(gab_post)) } if args.flags.twitter { - println!(">>>Twitter:"); - tokio_core.run(twitter.post(&message, &tags).map_err(error_formatter!("Cannot tweet.")).and_then(api::twitter::Client::handle_post))?; + let tweet = twitter.post(&message, &tags).map_err(error_formatter!("Cannot tweet.")).then(api::twitter::Client::handle_post); + jobs.push(Box::new(tweet)) } + + tokio_core.run(futures::future::join_all(jobs)).unwrap(); }, cli::Commands::Post(message, tags, Some(image)) => { + let mut jobs: Vec>> = vec![]; let image = utils::open_image(image).map_err(error_formatter!("Cannot open image!"))?; if args.flags.gab { - println!(">>>Gab:"); let gab_post = gab.upload_image(&image).map_err(error_formatter!("Cannot upload image.")) .and_then(handle_bad_hyper_response!("Cannot upload image.")) .and_then(|response| response.body().concat2().map_err(error_formatter!("Cannot read image upload's response"))) - .and_then(move |body| serde_json::from_slice(&body).map_err(error_formatter!("Cannot parse image upload's response"))) + .and_then(|body| serde_json::from_slice(&body).map_err(error_formatter!("Cannot parse image upload's response"))) .and_then(|response: api::gab::payload::UploadResponse| gab.post_w_images(&message, &tags, &[response.id]).map_err(error_formatter!("Cannot post."))) - .and_then(api::gab::Client::handle_post); - tokio_core.run(gab_post)?; + .then(api::gab::Client::handle_post); + jobs.push(Box::new(gab_post)) } if args.flags.twitter { - println!(">>>Twitter:"); let tweet = twitter.upload_image(&image).map_err(error_formatter!("Cannot upload image.")) .and_then(|rsp| twitter.post_w_images(&message, &tags, &[rsp.response.id]).map_err(error_formatter!("Cannot tweet."))) - .and_then(api::twitter::Client::handle_post); - tokio_core.run(tweet)?; + .then(api::twitter::Client::handle_post); + jobs.push(Box::new(tweet)) } + + tokio_core.run(futures::future::join_all(jobs)).unwrap(); } - } + }; + Ok(0) } diff --git a/src/utils.rs b/src/utils.rs index f0af9e7..ed183f1 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -11,7 +11,7 @@ use self::io::{ BufReader, Read }; - +use ::futures::future; use ::mime_guess::{ Mime, guess_mime_type @@ -64,3 +64,7 @@ pub fn get_config() -> PathBuf { result } + +pub fn empty_future_job() -> future::FutureResult<(), ()> { + future::ok(()) +}