use std::fmt;
use semver::Version;
use crate::error::{Error, ErrorKind};
#[derive(Debug, Clone, Default, PartialEq, Eq)]
#[non_exhaustive]
pub enum UpdateStatus {
#[default]
Idle,
Checking,
UpToDate,
Available(Version),
Downloading { downloaded: u64, total: Option<u64> },
Installing,
Staged(Version),
Errored(UpdateError),
}
impl UpdateStatus {
#[must_use]
pub fn is_busy(&self) -> bool {
matches!(
self,
Self::Checking | Self::Downloading { .. } | Self::Installing
)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UpdateError {
kind: ErrorKind,
message: String,
}
impl UpdateError {
pub fn new(kind: ErrorKind, message: impl Into<String>) -> Self {
Self {
kind,
message: message.into(),
}
}
#[must_use]
pub fn kind(&self) -> ErrorKind {
self.kind
}
#[must_use]
pub fn message(&self) -> &str {
&self.message
}
}
impl fmt::Display for UpdateError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.message)
}
}
impl std::error::Error for UpdateError {}
impl From<&Error> for UpdateError {
fn from(error: &Error) -> Self {
Self::new(error.kind(), error.to_string())
}
}
impl From<Error> for UpdateError {
fn from(error: Error) -> Self {
Self::from(&error)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn keeps_the_kind_and_message_of_an_error() {
let error = UpdateError::from(Error::Http("GET x -> 503".into()));
assert_eq!(error.kind(), ErrorKind::Network);
assert_eq!(error.message(), "http error: GET x -> 503");
assert_eq!(error.to_string(), error.message());
}
}