use crate::wire_messages::{IndexQuery, LsResponse, ReadQuery};
use serde::{Deserialize, Serialize};
use std::{fmt, time::Duration};
use thiserror::Error;
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct UiClientMessage {
pub id: u32,
pub command: Command,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub enum Command {
Ls(IndexQuery, Option<String>),
Read(ReadQuery, String),
Download { path: String, peer_name: String },
Shares(IndexQuery),
AddShare(String),
RemoveShare(String),
Requests,
RequestedFiles(u32),
RemoveRequest(u32),
ConnectDirect(String),
Close,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub enum UiServerMessage {
Response {
id: u32,
response: Result<UiResponse, UiServerError>,
},
Event(UiEvent),
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub enum UiEvent {
PeerConnected {
name: String,
peer_type: PeerRemoteOrSelf,
},
PeerDisconnected { name: String },
Uploaded(UploadInfo),
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub enum PeerRemoteOrSelf {
Remote,
Me {
os_home_dir: Option<String>,
announce_address: String,
},
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct UiDownloadRequest {
pub path: String,
pub progress: u64,
pub total_size: u64,
pub request_id: u32,
pub timestamp: Duration,
pub peer_name: String,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct UiRequestedFile {
pub path: String,
pub size: u64,
pub request_id: u32,
pub downloaded: bool,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct UploadInfo {
pub path: String,
pub bytes_read: u64,
pub speed: usize,
pub peer_name: String,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub enum UiResponse {
Download(DownloadResponse),
Read(Vec<u8>),
Ls(LsResponse, String),
Shares(LsResponse),
AddShare(u32),
RemoveShare,
Requests(Vec<UiDownloadRequest>),
RequestedFiles(Vec<UiRequestedFile>),
EndResponse,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Error, Clone)]
pub enum UiServerError {
#[error("Cannot connect: {0}")]
ConnectionError(String),
#[error("Request error")]
RequestError, #[error("Error when updating shared directory")]
ShareError(String),
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub enum DownloadInfo {
Requested(Duration),
Downloading {
path: String,
bytes_read: u64,
total_bytes_read: u64,
speed: u32,
},
Completed(Duration),
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct DownloadResponse {
pub path: String,
pub peer_name: String,
pub download_info: DownloadInfo,
}
impl fmt::Display for DownloadResponse {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.download_info {
DownloadInfo::Requested(_time) => {
write!(f, "Requested {}/{}", self.peer_name, self.path)
}
DownloadInfo::Downloading {
path,
bytes_read,
total_bytes_read,
speed,
} => {
write!(
f,
"Downloading {}/{} {} bytes read, {} total bytes read, {} bps",
self.peer_name, path, bytes_read, total_bytes_read, speed
)
}
DownloadInfo::Completed(_time) => {
write!(f, "Completed {}/{}", self.peer_name, self.path)
}
}
}
}