use crate::msg::*; use btlib::{crypto::Creds, BlockMeta, BlockPath, Result}; use btmsg::{receiver, MsgCallback, MsgReceived, Receiver}; use core::future::Future; use std::{net::IpAddr, sync::Arc}; use tokio::runtime::Handle as RuntimeHandle; pub trait FsProvider { type LookupFut<'c>: Send + Future> where Self: 'c; fn lookup<'c>(&'c self, from: &'c Arc, msg: Lookup<'c>) -> Self::LookupFut<'c>; type CreateFut<'c>: Send + Future> where Self: 'c; fn create<'c>(&'c self, from: &'c Arc, msg: Create<'c>) -> Self::CreateFut<'c>; type OpenFut<'c>: Send + Future> where Self: 'c; fn open<'c>(&'c self, from: &'c Arc, msg: Open) -> Self::OpenFut<'c>; fn read<'c, R, F>(&'c self, from: &'c Arc, msg: Read, callback: F) -> Result where F: 'c + Send + FnOnce(&[u8]) -> R; type WriteFut<'c>: Send + Future> where Self: 'c; fn write<'c>(&'c self, from: &'c Arc, msg: Write) -> Self::WriteFut<'c>; type FlushFut<'c>: Send + Future> where Self: 'c; fn flush<'c>(&'c self, from: &'c Arc, msg: Flush) -> Self::FlushFut<'c>; type ReadDirFut<'c>: Send + Future> where Self: 'c; fn read_dir<'c>(&'c self, from: &'c Arc, msg: ReadDir) -> Self::ReadDirFut<'c>; type LinkFut<'c>: Send + Future> where Self: 'c; fn link<'c>(&'c self, from: &'c Arc, msg: Link) -> Self::LinkFut<'c>; type UnlinkFut<'c>: Send + Future> where Self: 'c; fn unlink<'c>(&'c self, from: &'c Arc, msg: Unlink) -> Self::UnlinkFut<'c>; type ReadMetaFut<'c>: Send + Future> where Self: 'c; fn read_meta<'c>(&'c self, from: &'c Arc, msg: ReadMeta) -> Self::ReadMetaFut<'c>; type WriteMetaFut<'c>: Send + Future> where Self: 'c; fn write_meta<'c>(&'c self, from: &'c Arc, msg: WriteMeta) -> Self::WriteMetaFut<'c>; type CloseFut<'c>: Send + Future> where Self: 'c; fn close<'c>(&'c self, from: &'c Arc, msg: Close) -> Self::CloseFut<'c>; type ForgetFut<'c>: Send + Future> where Self: 'c; fn forget<'c>(&'c self, from: &'c Arc, msg: Forget) -> Self::ForgetFut<'c>; type LockFut<'c>: Send + Future> where Self: 'c; fn lock<'c>(&'c self, from: &'c Arc, msg: Lock) -> Self::LockFut<'c>; type UnlockFut<'c>: Send + Future> where Self: 'c; fn unlock<'c>(&'c self, from: &'c Arc, msg: Unlock) -> Self::UnlockFut<'c>; } struct ServerCallback

{ provider: Arc

, } impl

ServerCallback

{ fn new(provider: Arc

) -> Self { Self { provider } } } impl

Clone for ServerCallback

{ fn clone(&self) -> Self { Self { provider: self.provider.clone(), } } } impl MsgCallback for ServerCallback

{ type Arg<'de> = FsMsg<'de>; type CallFut<'de> = impl 'de + Future>; fn call<'de>(&'de self, arg: MsgReceived>) -> Self::CallFut<'de> { async move { let (from, body, replier) = arg.into_parts(); let provider = &self.provider; let reply = match body { FsMsg::Lookup(lookup) => FsReply::Lookup(provider.lookup(&from, lookup).await?), FsMsg::Create(create) => FsReply::Create(provider.create(&from, create).await?), FsMsg::Open(open) => FsReply::Open(provider.open(&from, open).await?), FsMsg::Read(read) => { return provider.read(&from, read, move |data| { let mut replier = replier.unwrap(); RuntimeHandle::current() .block_on(replier.reply(FsReply::Read(ReadReply { data }))) })?; } FsMsg::Write(write) => FsReply::Write(provider.write(&from, write).await?), FsMsg::Flush(flush) => FsReply::Ack(provider.flush(&from, flush).await?), FsMsg::ReadDir(read_dir) => { FsReply::ReadDir(provider.read_dir(&from, read_dir).await?) } FsMsg::Link(link) => FsReply::Ack(provider.link(&from, link).await?), FsMsg::Unlink(unlink) => FsReply::Ack(provider.unlink(&from, unlink).await?), FsMsg::ReadMeta(read_meta) => { FsReply::ReadMeta(provider.read_meta(&from, read_meta).await?) } FsMsg::WriteMeta(write_meta) => { FsReply::Ack(provider.write_meta(&from, write_meta).await?) } FsMsg::Close(close) => FsReply::Ack(provider.close(&from, close).await?), FsMsg::Forget(forget) => FsReply::Ack(provider.forget(&from, forget).await?), FsMsg::Lock(lock) => FsReply::Ack(provider.lock(&from, lock).await?), FsMsg::Unlock(unlock) => FsReply::Ack(provider.unlock(&from, unlock).await?), }; replier.unwrap().reply(reply).await } } } pub fn new_fs_server( ip_addr: IpAddr, creds: Arc, provider: Arc

, ) -> Result where C: 'static + Send + Sync + Creds, P: 'static + Send + Sync + FsProvider, { receiver(ip_addr, creds, ServerCallback::new(provider)) }