I'm on my way of converting to Rust from the ML family, but I'm finding it hard at some strange places I'm not used to having problems.
I'm trying to use hyper
for http handling but can't seem to get tokio
to work.
I have tried to copy paste this example:
use hyper::{body::HttpBody as _, Client};
use tokio::io::{self, AsyncWriteExt as _};
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
#[tokio::main]
async fn main() -> Result<()> {
// ...
fetch_url(url).await
}
async fn fetch_url(url: hyper::Uri) -> Result<()> {
// ...
Ok(())
}
Here is my Cargo.toml
:
[package]
name = "projectname"
version = "0.1.0"
authors = ["username"]
edition = "2018"
[dependencies]
hyper = "0.14.4"
tokio = "1.2.0"
It is complaining that it can't find the io
crate, and that main
has an invalid type impl Future
, and that it can't find main
in tokio
:
error[E0433]: failed to resolve: could not find `main` in `tokio`
--> src/main.rs:9:10
|
9 | #[tokio::main]
| ^^^^ could not find `main` in `tokio`
error[E0277]: `main` has invalid return type `impl Future`
--> src/main.rs:10:20
|
10 | async fn main() -> Result<()> {
| ^^^^^^^^^^ `main` can only return types that implement `Termination`
error[E0432]: unresolved import `hyper::Client`
--> src/main.rs:3:34
|
3 | use hyper::{body::HttpBody as _, Client};
| ^^^^^^ no `Client` in the root
error[E0425]: cannot find function `stdout` in module `io`
--> src/main.rs:45:13
|
45 | io::stdout().write_all(&chunk).await?;
| ^^^^^^ not found in `io`
|
error[E0432]: unresolved import `tokio::io::AsyncWriteExt`
--> src/main.rs:4:23
|
4 | use tokio::io::{self, AsyncWriteExt as _};
| -------------^^^^^
| |
| no `AsyncWriteExt` in `io`
| help: a similar name exists in the module: `AsyncWrite`
Is #[tokio::main]
and client
not in hyper?
The tokio::main
macro converts an async main
to a regular main that spawns a runtime. However, because the macro is not found is scope, it cannot transform your main function, and the compiler is complaining that your main has an invalid return type of impl Future
. To fix this, you have to enable the required features to import the main
macro:
tokio = { version = "1.2.0", features = ["rt", "macros"] }
You also have to enable the io-util
feature to access io::AsyncWriteExt
, and the io-std
feature to access io::stdout
. To simplify this, tokio
provides the full
feature flag, which will enable all optional features:
tokio = { version = "1.2.0", features = ["full"] }
You also need hyper's client
and http
feature flags to resolve the Client
import:
hyper = { version = "0.14.4", features = ["client", "http1", "http2"] }