Top Related Projects
A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...
Async version of the Rust standard library
A small and fast async runtime for Rust
async fn(Request) -> Result<Response, Error>
Actor framework for Rust.
An HTTP library for Rust
Quick Overview
Futures-rs is a Rust library that provides zero-cost abstractions for asynchronous programming. It offers a set of traits, types, and functions that enable efficient and composable asynchronous operations, serving as a foundation for many async Rust libraries and applications.
Pros
- Zero-cost abstractions for async programming
- Highly composable and flexible
- Well-integrated with Rust's async/await syntax
- Extensive ecosystem support and community adoption
Cons
- Learning curve for developers new to async programming
- Occasional complexity in error handling and type inference
- Some features may require nightly Rust for full functionality
- Documentation can be overwhelming for beginners
Code Examples
- Basic future creation and execution:
use futures::executor::block_on;
async fn hello_world() -> String {
"Hello, world!".to_string()
}
fn main() {
let future = hello_world();
let result = block_on(future);
println!("{}", result);
}
- Chaining futures with
and_then
:
use futures::future::{self, FutureExt};
async fn step1() -> u32 { 1 }
async fn step2(x: u32) -> u32 { x + 1 }
let future = future::ready(())
.then(|_| step1())
.and_then(step2);
assert_eq!(block_on(future), 2);
- Concurrent execution with
join
:
use futures::future::{self, join};
async fn task1() -> u32 { 1 }
async fn task2() -> u32 { 2 }
let future = join(task1(), task2());
let (result1, result2) = block_on(future);
assert_eq!(result1, 1);
assert_eq!(result2, 2);
Getting Started
To use futures-rs in your Rust project, add the following to your Cargo.toml
:
[dependencies]
futures = "0.3"
Then, in your Rust code:
use futures::prelude::*;
async fn example() {
println!("Hello from an async function!");
}
fn main() {
futures::executor::block_on(example());
}
This sets up the basic environment for using futures in your Rust project. You can now start writing asynchronous code using the futures-rs library.
Competitor Comparisons
A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...
Pros of tokio
- Comprehensive async runtime with built-in scheduler and executor
- Provides a full ecosystem of async I/O primitives and utilities
- Optimized for performance and scalability in production environments
Cons of tokio
- Steeper learning curve due to more complex API and concepts
- Larger dependency footprint and compilation times
- May be overkill for simpler async tasks or smaller projects
Code Comparison
futures-rs:
use futures::executor::block_on;
use futures::future::Future;
async fn hello_world() -> String {
"Hello, World!".to_string()
}
let future = hello_world();
let result = block_on(future);
tokio:
use tokio;
#[tokio::main]
async fn main() {
println!("Hello, World!");
}
Summary
futures-rs focuses on providing core async abstractions and primitives, while tokio offers a full-featured async runtime and ecosystem. futures-rs is lighter-weight and more flexible, but tokio provides a more complete solution for building async applications. The choice between them depends on the specific needs of your project, with tokio being better suited for larger, performance-critical applications, and futures-rs being ideal for more targeted async functionality or as a foundation for custom async implementations.
Async version of the Rust standard library
Pros of async-std
- Provides a more complete and user-friendly async runtime
- Offers a familiar API design similar to the Rust standard library
- Includes additional utilities and abstractions for common async tasks
Cons of async-std
- Larger dependency footprint compared to futures-rs
- May have slightly higher overhead due to its more comprehensive feature set
- Less flexibility for users who want to build custom async runtimes
Code Comparison
futures-rs:
use futures::executor::block_on;
use futures::future::Future;
async fn hello_world() {
println!("Hello, world!");
}
fn main() {
block_on(hello_world());
}
async-std:
use async_std::task;
async fn hello_world() {
println!("Hello, world!");
}
fn main() {
task::block_on(hello_world());
}
Summary
futures-rs is a lower-level library that provides the building blocks for async programming in Rust. It's more lightweight and flexible but requires more setup for complex async operations.
async-std, on the other hand, offers a more complete async runtime with a familiar API design. It's easier to use for beginners and provides additional utilities, but comes with a larger dependency footprint and slightly higher overhead.
The choice between the two depends on the specific needs of the project, with futures-rs being better for low-level control and async-std for ease of use and rapid development.
A small and fast async runtime for Rust
Pros of smol
- Lightweight and minimalistic design, focusing on simplicity and ease of use
- Provides a complete async runtime with a smaller API surface
- Offers better performance for certain use cases, especially with many concurrent tasks
Cons of smol
- Less mature and less widely adopted compared to futures-rs
- May lack some advanced features and utilities present in futures-rs
- Smaller ecosystem and fewer third-party integrations
Code Comparison
smol example:
use smol::Timer;
use std::time::Duration;
smol::block_on(async {
Timer::after(Duration::from_secs(1)).await;
println!("One second has passed");
})
futures-rs example:
use futures::executor::block_on;
use futures_timer::Delay;
use std::time::Duration;
block_on(async {
Delay::new(Duration::from_secs(1)).await;
println!("One second has passed");
})
Both examples demonstrate a simple async operation with a timer. smol provides a more integrated approach with its own runtime, while futures-rs requires additional crates for similar functionality. The smol example is slightly more concise and uses its built-in Timer, whereas futures-rs relies on the separate futures-timer crate for the Delay functionality.
async fn(Request) -> Result<Response, Error>
Pros of Tower
- Provides a higher-level abstraction for building robust network services
- Offers middleware-based architecture for composable and reusable components
- Includes built-in support for rate limiting, load balancing, and retries
Cons of Tower
- Steeper learning curve due to more complex abstractions
- Less flexible for low-level async programming tasks
- Smaller community and ecosystem compared to Futures
Code Comparison
Tower example:
let service = ServiceBuilder::new()
.rate_limit(5, Duration::from_secs(1))
.service(MyService::new());
Futures example:
let future = async {
let result = some_async_operation().await;
process_result(result)
};
Summary
Tower is a higher-level framework built on top of Futures, providing more advanced features for building network services. It offers a middleware-based architecture and built-in components for common tasks. However, it may be overkill for simpler async programming needs and has a steeper learning curve.
Futures, on the other hand, is a lower-level library that provides the fundamental building blocks for asynchronous programming in Rust. It's more flexible and widely used but requires more manual implementation of advanced features that Tower provides out of the box.
Choose Tower for building complex network services with reusable components, and Futures for more general-purpose async programming tasks or when you need finer control over the async runtime.
Actor framework for Rust.
Pros of actix
- Provides a complete, high-performance web framework
- Includes an actor system for concurrent and distributed programming
- Offers built-in WebSocket support and HTTP/2
Cons of actix
- Steeper learning curve due to its comprehensive feature set
- More opinionated architecture, which may limit flexibility in some cases
- Larger codebase and potential overhead for simpler applications
Code Comparison
futures-rs:
use futures::executor::block_on;
async fn hello_world() -> String {
"Hello, World!".to_string()
}
let future = hello_world();
let result = block_on(future);
actix:
use actix_web::{get, App, HttpServer, Responder};
#[get("/")]
async fn hello() -> impl Responder {
"Hello, World!"
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().service(hello))
.bind("127.0.0.1:8080")?
.run()
.await
}
Summary
futures-rs is a lower-level library focused on asynchronous programming primitives, while actix is a full-featured web framework built on top of those primitives. futures-rs provides more flexibility and is lighter-weight, making it suitable for a wider range of asynchronous programming tasks. actix, on the other hand, offers a more complete solution for web development, including an actor system and built-in HTTP features, but comes with a steeper learning curve and more opinionated structure.
An HTTP library for Rust
Pros of Hyper
- Specialized for HTTP: Hyper is a full-featured HTTP client and server implementation, offering more specific functionality for web-related tasks.
- Higher-level abstractions: Provides ready-to-use components for building HTTP applications, reducing boilerplate code.
- Performance-focused: Optimized for HTTP workloads, potentially offering better performance for web-centric applications.
Cons of Hyper
- Limited scope: Focused solely on HTTP, while Futures-rs is a general-purpose asynchronous programming library.
- Steeper learning curve: May require more domain-specific knowledge to use effectively compared to the more generic Futures-rs.
- Potentially over-engineered: For simple HTTP tasks, Hyper might be more complex than necessary.
Code Comparison
Futures-rs (basic future):
use futures::future::Future;
let future = async {
// Asynchronous operation
42
};
Hyper (basic HTTP request):
use hyper::{Client, Uri};
let client = Client::new();
let uri = "http://example.com".parse::<Uri>().unwrap();
let resp = client.get(uri).await?;
Both libraries support asynchronous programming, but Hyper provides higher-level abstractions specific to HTTP operations, while Futures-rs offers more general-purpose asynchronous primitives.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Zero-cost asynchronous programming in Rust
futures-rs
is a library providing the foundations for asynchronous programming in Rust.
It includes key trait definitions like Stream
, as well as utilities like join!
,
select!
, and various futures combinator methods which enable expressive asynchronous
control flow.
Usage
Add this to your Cargo.toml
:
[dependencies]
futures = "0.3"
The current futures
requires Rust 1.56 or later.
Feature std
Futures-rs works without the standard library, such as in bare metal environments.
However, it has a significantly reduced API surface. To use futures-rs in
a #[no_std]
environment, use:
[dependencies]
futures = { version = "0.3", default-features = false }
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Top Related Projects
A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...
Async version of the Rust standard library
A small and fast async runtime for Rust
async fn(Request) -> Result<Response, Error>
Actor framework for Rust.
An HTTP library for Rust
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot