veloren/network/examples/fileshare/commands.rs
Marcel Märtens 5aa1940ef8 get rid of async_std::channel
switch to `tokio` and `async_channel` crate.
I wanted to do tokio first, but it doesnt feature Sender::close(), thus i included async_channel
Got rid of `futures` and only need `futures_core` and `futures_util`.

Tokio does not support `Stream` and `StreamExt` so for now i need to use `tokio-stream`, i think this will go in `std` in the future

Created `b2b_close_stream_opened_sender_r` as the shutdown procedure does not need a copy of a Sender, it just need to stop it.

Various adjustments, e.g. for `select!` which now requieres a `&mut` for oneshots.

Future things to do:
 - Use some better signalling than oneshot<()> in some cases.
 - Use a Watch for the Prio propergation (impl. it ofc)
 - Use Bounded Channels in order to improve performance
 - adjust tests coding

bring tests to work
2021-02-17 12:38:53 +01:00

86 lines
2.0 KiB
Rust

use rand::Rng;
use serde::{Deserialize, Serialize};
use std::path::{Path, PathBuf};
use tokio::fs;
use veloren_network::{Participant, ProtocolAddr, Stream};
use std::collections::HashMap;
#[derive(Debug)]
pub enum LocalCommand {
Shutdown,
Disconnect,
Connect(ProtocolAddr),
List,
Serve(FileInfo),
Get(u32, Option<String>),
}
#[derive(Serialize, Deserialize, Debug)]
pub enum Command {
List,
Get(u32),
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct FileInfo {
id: u32,
pub path: String,
pub size: u64,
pub hash: String,
}
pub struct RemoteInfo {
infos: HashMap<u32, FileInfo>,
_participant: Participant,
pub cmd_out: Stream,
pub file_out: Stream,
}
impl FileInfo {
pub async fn new(path: &Path) -> Option<Self> {
let mt = match fs::metadata(&path).await {
Err(e) => {
println!(
"Cannot get metadata for file: {:?}, does it exist? Error: {:?}",
&path, &e
);
return None;
},
Ok(mt) => mt,
};
let size = mt.len();
Some(Self {
id: rand::thread_rng().gen(),
path: path.as_os_str().to_os_string().into_string().unwrap(),
size,
hash: "<none>".to_owned(),
})
}
pub async fn load(&self) -> Result<Vec<u8>, std::io::Error> { fs::read(self.path()).await }
pub fn id(&self) -> u32 { self.id }
pub fn path(&self) -> PathBuf { self.path.parse().unwrap() }
}
impl RemoteInfo {
pub fn new(cmd_out: Stream, file_out: Stream, participant: Participant) -> Self {
Self {
infos: HashMap::new(),
_participant: participant,
cmd_out,
file_out,
}
}
pub fn get_info(&self, id: u32) -> Option<FileInfo> { self.infos.get(&id).cloned() }
pub fn insert_infos(&mut self, mut fi: Vec<FileInfo>) {
for fi in fi.drain(..) {
self.infos.insert(fi.id(), fi);
}
}
}