ugi 0.2.1

Runtime-agnostic Rust request client with HTTP/1.1, HTTP/2, HTTP/3, H2C, WebSocket, SSE, and gRPC support
Documentation
#[cfg(feature = "h2")]
use futures_lite::future::block_on;

#[cfg(feature = "h2")]
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
struct ClientEvent {
    text: String,
}

#[cfg(feature = "h2")]
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
struct ServerEvent {
    text: String,
}

#[cfg(feature = "h2")]
fn main() -> Result<(), Box<dyn std::error::Error>> {
    block_on(async move {
        let client = ugi::Client::builder()
            .bearer_auth("token")?
            .http2_only()
            .build()?;
        let mut call = client
            .grpc("https://grpc.example.com/chat.ChatService/Connect")
            .open_duplex()
            .await?;

        call.send_message(&ClientEvent {
            text: "hello".to_owned(),
        })
        .await?;

        if let Some(event) = call.next_message::<ServerEvent>().await? {
            println!("server: {}", event.text);
        }

        call.send_message(&ClientEvent {
            text: "goodbye".to_owned(),
        })
        .await?;

        call.finish_sending();
        let status = call.finish().await?;
        println!("grpc-status={} {}", status.code(), status.message());
        Ok(())
    })
}

#[cfg(not(feature = "h2"))]
fn main() {
    eprintln!("This example requires the `h2` feature.");
}