Expand description
§asansio
This library contains the async/await state machine for the sans-io design pattern. See sans I/O for network protocols documentation to familiar with the concept. Writing network protocol without performing I/O operations means creating a state machine. Manually creating a state machine could be a tedious process. As Rust async/await concept is an actual state machine with implicit states created during compilation, this library is an experiment with using async/await to provide such state machine automatically. Let’s check if this is good solution to the problem.
This crate could be used also for non network protocol cases, everywhere there is a need for creating a state machine.
This is no_std
crate and it doesn’t allocate on the heap.
§Usage
See this simple example:
struct Request<'a>(&'a [u8]);
struct Response<'a>(&'a [u8]);
async fn sans_task<'a>(sans: Sans<Request<'a>, Response<'a>>) {
let mut request_buf = [1u8; 10];
let response = sans.start(&Request(&request_buf)).await;
assert_eq!(response.response().unwrap().0, [2; 20]);
request_buf.fill(3);
let response = sans.handle(response, &Request(&request_buf)).await;
assert_eq!(response.response().unwrap().0, [4; 20]);
}
let (sans, io) = asansio::new();
let task = pin!(sans_task(sans));
let request = io.start(task).unwrap();
assert_eq!(request.request().unwrap().0, [1; 10]);
let mut response_buf = [2; 20];
let request = io.handle(request, &Response(&response_buf)).unwrap();
assert_eq!(request.request().unwrap().0, [3; 10]);
response_buf.fill(4);
assert!(io.handle(request, &Response(&response_buf)).is_none());
This crate divides a problem into two parts. The first Sans
takes care of the state machine
independent of the I/O and the second Io
is responsible with I/O communication. There are
two types to manage them: the Io and the Sans, which are constructed by the new function.
These two parts communicate using Request
and Respond
types, which are defined by the user
(for real scenarios they could be enums
).
Sans
starts communicating with Io
using Sans::start and providing the initial Request
;
it returns the SansResponse from the Io
. Io
starts sans task by using Io::start which
returns IoRequest from Sans
. The later communication is done using Sans::handle and
Io::handle, which consume SansResponse and IoRequest.
See also more examples.
§Safety
The crate uses unsafe
parts for preparing a proper async/await
infrastructure. Safety is
guaranteed by consuming the latest IoRequest and SansResponse - these handlers store
Request
and Response
objects and their lifetime is limited to the adjecent calls.
Structs§
- Io
- Manages the Io part
- IoRequest
- The holder of the Request from the Sans to Io
- Sans
- Manages the Sans part
- Sans
Handle - The Future helper for handling data between Io and Sans
- Sans
Response - The holder of the Response from the Io to Sans
Functions§
- new
- Creates a two parts: Sans and Io for the specified Request and Response.