#![feature(generic_associated_types, type_alias_impl_trait)] extern crate real_async_trait; use std::collections::BTreeMap; use std::str; use real_async_trait::real_async_trait; pub type Errno = usize; pub const ENOENT: usize = 1; pub const EBADF: usize = 2; #[real_async_trait] pub trait AsyncScheme { async fn open<'a>(&'a mut self, path: &'a [u8], flags: usize) -> Result; async fn close<'a>(&'a mut self, fd: usize) -> Result<(), Errno>; async fn read<'a>(&'a mut self, fd: usize, num: &'a mut u64) -> Result<(), Errno>; async fn write<'a>(&'a mut self, fd: usize, num: &'a u64) -> Result<(), Errno>; } struct NumberScheme { handles: BTreeMap, } #[real_async_trait] impl AsyncScheme for NumberScheme { async fn open<'a>(&'a mut self, path: &'a [u8], _flags: usize) -> Result { let path_str = str::from_utf8(path).or(Err(ENOENT))?; let num = path_str.parse::().or(Err(ENOENT))?; self.handles.insert(num, 0); Ok(num) } async fn close<'a>(&'a mut self, fd: usize) -> Result<(), Errno> { if self.handles.remove(&fd).is_none() { return Err(EBADF); } Ok(()) } async fn read<'a>(&'a mut self, fd: usize, num: &'a mut u64) -> Result<(), Errno> { let handle = self.handles.get(&fd).ok_or(ENOENT)?; *num = *handle; Ok(()) } async fn write<'a>(&'a mut self, fd: usize, num: &'a u64) -> Result<(), Errno> { let handle = self.handles.get_mut(&fd).ok_or(ENOENT)?; *handle = *num; Ok(()) } } #[async_std::main] async fn main() -> Result<(), Errno> { let mut numberscheme = NumberScheme { handles: BTreeMap::new(), }; let mut number_buf = 0u64; let input_buf = 420u64; println!("Opening valuable number container `1337`"); let fd = numberscheme.open(b"1337", 1).await?; println!("Opened number container `1337`"); println!( "Initiating read from number container `1337` (fd {}), into buffer at {:p}", fd, &number_buf as *const _ ); numberscheme.read(fd, &mut number_buf).await?; println!( "Completed read from number container `1337` (fd {}), new value: {}", fd, number_buf ); println!( "Initiating write into number container `1337` (fd {}), from buffer at {:p}", fd, &input_buf as *const _ ); numberscheme.write(fd, &input_buf).await?; println!( "Completed write into number container `1337` (fd {}), new value: {}", fd, input_buf ); println!( "Initiating second read from number container `1337` (fd {}), into buffer at {:p}", fd, &number_buf as *const _ ); numberscheme.read(fd, &mut number_buf).await?; println!( "Completed second read from number container `1337` (fd {}), new value: {}", fd, number_buf ); println!("Closing number container `1337` (fd {})", fd); numberscheme.close(fd).await?; println!("Number container `1337` (fd {}) closed", fd); Ok(()) }