use crate::install::event::InstallProgress;
use crate::install::file_selection::is_weight_path;
use crate::install::provider::InstallProviderId;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct InstallPlanFile {
pub path: String,
pub bytes: Option<i64>,
}
impl InstallPlanFile {
pub fn new(path: impl Into<String>, bytes: Option<i64>) -> Self {
Self {
path: path.into(),
bytes,
}
}
pub fn is_weight(&self) -> bool {
is_weight_path(&self.path)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct InstallPlan {
pub provider: InstallProviderId,
pub reference: String,
pub display_name: String,
pub revision: Option<String>,
pub files: Vec<InstallPlanFile>,
pub total_bytes: Option<i64>,
pub remaining_bytes: Option<i64>,
pub destination: String,
pub requires_auth: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct InstallSearchHit {
pub provider: InstallProviderId,
pub reference: String,
pub name: String,
pub downloads: Option<i64>,
pub likes: Option<i64>,
pub updated_at: Option<i64>,
}
impl InstallSearchHit {
pub fn id(&self) -> String {
format!("{}|{}", self.provider.as_str(), self.reference)
}
}
impl InstallPlan {
pub fn new(
provider: InstallProviderId,
reference: impl Into<String>,
display_name: impl Into<String>,
destination: impl Into<String>,
) -> Self {
Self {
provider,
reference: reference.into(),
display_name: display_name.into(),
revision: None,
files: Vec::new(),
total_bytes: None,
remaining_bytes: None,
destination: destination.into(),
requires_auth: false,
}
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
pub struct InstallBrowseResult {
pub hits: Vec<InstallSearchHit>,
pub failure_hint: Option<String>,
}
impl InstallBrowseResult {
pub fn with_hits(hits: Vec<InstallSearchHit>) -> Self {
Self {
hits,
failure_hint: None,
}
}
pub fn failure(hint: impl Into<String>) -> Self {
Self {
hits: Vec::new(),
failure_hint: Some(hint.into()),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ActiveInstall {
pub id: String,
pub provider: InstallProviderId,
pub reference: String,
pub display_name: String,
pub total_bytes: Option<i64>,
pub progress: InstallProgress,
pub started_at: i64,
}
impl ActiveInstall {
pub fn new(
id: impl Into<String>,
provider: InstallProviderId,
reference: impl Into<String>,
display_name: impl Into<String>,
total_bytes: Option<i64>,
started_at: i64,
) -> Self {
Self {
id: id.into(),
provider,
reference: reference.into(),
display_name: display_name.into(),
total_bytes,
progress: InstallProgress::default(),
started_at,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn an_active_install_starts_at_zero_progress() {
let active = ActiveInstall::new(
"in-1",
InstallProviderId::huggingface(),
"org/Model",
"Model",
Some(1000),
42,
);
assert_eq!(active.progress, InstallProgress::default());
assert_eq!(active.progress.bytes_downloaded, 0);
assert_eq!(active.total_bytes, Some(1000));
assert_eq!(active.started_at, 42);
}
#[test]
fn a_browse_result_separates_hits_from_a_failure() {
assert!(InstallBrowseResult::default().hits.is_empty());
assert_eq!(
InstallBrowseResult::failure("down").failure_hint.as_deref(),
Some("down")
);
assert!(InstallBrowseResult::failure("down").hits.is_empty());
}
}