use thiserror::Error;
#[derive(Debug, Clone)]
pub struct SendError;
pub type StreamResult<T> = Result<T, StreamError>;
#[derive(Debug, Error)]
pub enum StreamError {
#[error("stream has already been closed")]
AlreadyClosed,
#[error("stream closed abnormally: {0}")]
AbnormalEnd(String),
#[error("UTF-8 decoding error: {0}")]
Utf8(#[from] std::string::FromUtf8Error),
#[error("incoming header was invalid")]
InvalidHeader,
#[error("expected chunk index to be exactly one more than the previous")]
MissedChunk,
#[error("read length exceeded total length specified in stream header")]
LengthExceeded,
#[error("stream data is incomplete")]
Incomplete,
#[error("unable to send packet")]
SendFailed,
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
#[error("internal error")]
Internal,
#[error("encryption type mismatch")]
EncryptionTypeMismatch,
#[error("stream header exceeds maximum size")]
HeaderTooLarge,
#[error("stream payload exceeds maximum size")]
PayloadTooLarge,
#[error("decompression failed")]
Decompression,
#[error("file name must be a plain file name without path separators or '..'")]
InvalidFileName,
}
#[derive(Clone, Copy, Default, Debug, Hash, Eq, PartialEq)]
pub struct StreamProgress {
pub(crate) chunk_index: u64,
pub(crate) bytes_processed: u64,
pub(crate) bytes_total: Option<u64>,
}
impl StreamProgress {
pub fn bytes_processed(&self) -> u64 {
self.bytes_processed
}
pub fn bytes_total(&self) -> Option<u64> {
self.bytes_total
}
pub fn percentage(&self) -> Option<f32> {
self.bytes_total.map(|total| {
if total == 0 {
1.0
} else {
self.bytes_processed as f32 / total as f32
}
})
}
}