Skip to content

Instantly share code, notes, and snippets.

@yoshuawuyts
Last active July 14, 2018 01:21
Show Gist options
  • Save yoshuawuyts/27987161b2ba1b0955a54db99a5131b2 to your computer and use it in GitHub Desktop.
Save yoshuawuyts/27987161b2ba1b0955a54db99a5131b2 to your computer and use it in GitHub Desktop.
use clap_port_flag::Port;
use futures::prelude::*;
use hyper::{Body, Response, Server, service::service_fn_ok};
use structopt::{StructOpt, structopt};
#[derive(Debug, StructOpt)]
struct Cli {
#[structopt(flatten)]
port: Port,
}
fn main() -> Result<(), Box<std::error::Error>> {
let listener = Cli::from_args().port.bind_tokio()?;
let server = Server::builder(listener.incoming())
.serve(|| service_fn_ok(|_| Response::new(Body::from("Hello World"))))
.map_err(|e| eprintln!("server error: {}", e));
tokio::run(server);
Ok(())
}
@yoshuawuyts
Copy link
Author

yoshuawuyts commented Jul 14, 2018

This'll be even better with async/await eventually. Something like this probably:

use clap_port_flag::Port;
use hyper::{Body, Response, Server};
use structopt::{StructOpt, structopt};

#[derive(Debug, StructOpt)]
struct Cli {
  #[structopt(flatten)]
  port: Port,
}

fn main() -> Result<(), Box<std::error::Error>> {
  let listener = Cli::from_args().port.bind_tokio()?;
  let server = Server::builder(listener.incoming());
  let server = async { for await _req in server.serve() {
    Response::new(Body::from("Hello World"))
  }};
  tokio::run(server);
  Ok(())
}

@yoshuawuyts
Copy link
Author

yoshuawuyts commented Jul 14, 2018

With a small nudge from Hyper, and hopefully no mandatory async blocks this might even become:

use clap_port_flag::Port;
use hyper::{Body, Response, Server};
use structopt::{StructOpt, structopt};

#[derive(Debug, StructOpt)]
struct Cli {
  #[structopt(flatten)]
  port: Port,
}

fn main() -> Result<(), Box<std::error::Error>> {
  let listener = Cli::from_args().port.bind_tokio()?;
  let server = for await _req in Server::listen(listener) {
    Response::from_string("Hello World")
  };
  tokio::run(server);
  Ok(())
}

@yoshuawuyts
Copy link
Author

yoshuawuyts commented Jul 14, 2018

Okay, it's late - this is the final version I would probably want to see. No probably timeline for any of this; but it'd be so good if this would eventually be possible!

Note: the event loop here would probably be implemented similar to the memory allocator. Something that most people don't need to worry about, but can be changed for constrained runtimes. To me it makes a lot of sense if eventually (e.g. a few years from now) most people don't have to worry about managing event loops for day-to-day operations. Just like most of us don't need to think about allocators.

use hyper::prelude::*;
use clap::prelude::*;

#[derive(Debug, Clap)]
struct Cli {
  #[clap(flatten)]
  port: clap::flags::Port,
}

async fn main() -> Result<(), Error> {
  let listener = Cli::from_args().port.bind()?;
  for await _req in Server::listen(listener) {
    Response::from_string("Hello World")
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment