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 handle = sans.start(&Request(&request_buf)).await;
assert_eq!(handle.message().unwrap().0, [2; 20]);
request_buf.fill(3);
let handle = sans.handle(handle, &Request(&request_buf)).await;
assert_eq!(handle.message().unwrap().0, [4; 20]);
}
let (sans, io) = asansio::new();
let task = pin!(sans_task(sans));
let handle = io.start(task).unwrap();
assert_eq!(handle.message().unwrap().0, [1; 10]);
let mut response_buf = [2; 20];
let handle = io.handle(handle, &Response(&response_buf)).unwrap();
assert_eq!(handle.message().unwrap().0, [3; 10]);
response_buf.fill(4);
assert!(io.handle(handle, &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 SansHandle from the Io. Io starts sans task by using Io::start which
returns IoHandle from Sans. The later communication is done using Sans::handle and
Io::handle, which consume SansHandle and IoHandle.
See also more examples.
§Safety
The crate uses unsafe parts for preparing a proper async/await infrastructure. Safety is
guaranteed by consuming the latest IoHandle and SansHandle - these handlers store
Request and Response objects and their lifetime is limited to the adjecent calls.
Structs§
- Io
- Manages the Io part
- IoHandle
- The holder of the Request from the Sans to Io
- Sans
- Manages the Sans part
- Sans
Handle - 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.