use std::collections::HashMap;
use std::fmt;
#[derive(Debug, Clone)]
pub struct ModelZooEntry {
pub id: String,
pub name: String,
pub description: String,
pub version: String,
pub author: AuthorInfo,
pub model_type: ModelZooType,
pub quality_score: f32,
pub tags: Vec<String>,
pub download_url: String,
pub size_bytes: u64,
pub sha256: String,
pub license: String,
pub created_at: String,
pub updated_at: String,
pub downloads: u64,
pub stars: u64,
pub metadata: HashMap<String, String>,
}
impl ModelZooEntry {
#[must_use]
pub fn new(id: impl Into<String>, name: impl Into<String>) -> Self {
Self {
id: id.into(),
name: name.into(),
description: String::new(),
version: "1.0.0".to_string(),
author: AuthorInfo::default(),
model_type: ModelZooType::Other,
quality_score: 0.0,
tags: Vec::new(),
download_url: String::new(),
size_bytes: 0,
sha256: String::new(),
license: "MIT".to_string(),
created_at: String::new(),
updated_at: String::new(),
downloads: 0,
stars: 0,
metadata: HashMap::new(),
}
}
#[must_use]
pub fn with_description(mut self, description: impl Into<String>) -> Self {
self.description = description.into();
self
}
#[must_use]
pub fn with_version(mut self, version: impl Into<String>) -> Self {
self.version = version.into();
self
}
#[must_use]
pub fn with_author(mut self, author: AuthorInfo) -> Self {
self.author = author;
self
}
#[must_use]
pub fn with_model_type(mut self, model_type: ModelZooType) -> Self {
self.model_type = model_type;
self
}
#[must_use]
pub fn with_quality_score(mut self, score: f32) -> Self {
self.quality_score = score.clamp(0.0, 100.0);
self
}
#[must_use]
pub fn with_tag(mut self, tag: impl Into<String>) -> Self {
self.tags.push(tag.into());
self
}
#[must_use]
pub fn with_download_url(mut self, url: impl Into<String>) -> Self {
self.download_url = url.into();
self
}
#[must_use]
pub fn with_size(mut self, size_bytes: u64) -> Self {
self.size_bytes = size_bytes;
self
}
#[must_use]
pub fn with_sha256(mut self, hash: impl Into<String>) -> Self {
self.sha256 = hash.into();
self
}
#[must_use]
pub fn with_license(mut self, license: impl Into<String>) -> Self {
self.license = license.into();
self
}
#[must_use]
pub fn with_timestamps(
mut self,
created: impl Into<String>,
updated: impl Into<String>,
) -> Self {
self.created_at = created.into();
self.updated_at = updated.into();
self
}
#[must_use]
pub fn with_metadata(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.metadata.insert(key.into(), value.into());
self
}
#[must_use]
pub fn human_size(&self) -> String {
human_bytes(self.size_bytes)
}
#[must_use]
pub fn matches_query(&self, query: &str) -> bool {
let query_lower = query.to_lowercase();
self.id.to_lowercase().contains(&query_lower)
|| self.name.to_lowercase().contains(&query_lower)
|| self.description.to_lowercase().contains(&query_lower)
|| self
.tags
.iter()
.any(|t| t.to_lowercase().contains(&query_lower))
}
#[must_use]
pub fn has_tag(&self, tag: &str) -> bool {
let tag_lower = tag.to_lowercase();
self.tags.iter().any(|t| t.to_lowercase() == tag_lower)
}
#[must_use]
pub fn quality_grade(&self) -> &'static str {
match self.quality_score {
s if s >= 97.0 => "A+",
s if s >= 93.0 => "A",
s if s >= 90.0 => "A-",
s if s >= 87.0 => "B+",
s if s >= 83.0 => "B",
s if s >= 80.0 => "B-",
s if s >= 77.0 => "C+",
s if s >= 73.0 => "C",
s if s >= 70.0 => "C-",
s if s >= 60.0 => "D",
_ => "F",
}
}
}
impl fmt::Display for ModelZooEntry {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "{} ({})", self.name, self.id)?;
writeln!(
f,
" Version: {} | Size: {} | Quality: {:.0} ({})",
self.version,
self.human_size(),
self.quality_score,
self.quality_grade()
)?;
if !self.description.is_empty() {
writeln!(f, " {}", self.description)?;
}
if !self.tags.is_empty() {
writeln!(f, " Tags: {}", self.tags.join(", "))?;
}
Ok(())
}
}
#[derive(Debug, Clone, Default)]
pub struct AuthorInfo {
pub name: String,
pub email: String,
pub url: Option<String>,
pub organization: Option<String>,
}
impl AuthorInfo {
#[must_use]
pub fn new(name: impl Into<String>, email: impl Into<String>) -> Self {
Self {
name: name.into(),
email: email.into(),
url: None,
organization: None,
}
}
#[must_use]
pub fn with_url(mut self, url: impl Into<String>) -> Self {
self.url = Some(url.into());
self
}
#[must_use]
pub fn with_organization(mut self, org: impl Into<String>) -> Self {
self.organization = Some(org.into());
self
}
}
impl fmt::Display for AuthorInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.name)?;
if !self.email.is_empty() {
write!(f, " <{}>", self.email)?;
}
if let Some(org) = &self.organization {
write!(f, " ({org})")?;
}
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum ModelZooType {
LinearRegression,
LogisticRegression,
DecisionTree,
RandomForest,
GradientBoosting,
Knn,
KMeans,
Svm,
NaiveBayes,
NeuralNetwork,
Ensemble,
TimeSeries,
#[default]
Other,
}
impl ModelZooType {
#[must_use]
pub const fn name(&self) -> &'static str {
match self {
Self::LinearRegression => "Linear Regression",
Self::LogisticRegression => "Logistic Regression",
Self::DecisionTree => "Decision Tree",
Self::RandomForest => "Random Forest",
Self::GradientBoosting => "Gradient Boosting",
Self::Knn => "K-Nearest Neighbors",
Self::KMeans => "K-Means",
Self::Svm => "SVM",
Self::NaiveBayes => "Naive Bayes",
Self::NeuralNetwork => "Neural Network",
Self::Ensemble => "Ensemble",
Self::TimeSeries => "Time Series",
Self::Other => "Other",
}
}
#[must_use]
pub const fn category(&self) -> ModelCategory {
match self {
Self::LinearRegression => ModelCategory::Regression,
Self::LogisticRegression
| Self::DecisionTree
| Self::RandomForest
| Self::GradientBoosting
| Self::Knn
| Self::Svm
| Self::NaiveBayes => ModelCategory::Classification,
Self::KMeans => ModelCategory::Clustering,
Self::NeuralNetwork => ModelCategory::DeepLearning,
Self::Ensemble => ModelCategory::Ensemble,
Self::TimeSeries => ModelCategory::TimeSeries,
Self::Other => ModelCategory::Other,
}
}
}
impl fmt::Display for ModelZooType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.name())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ModelCategory {
Regression,
Classification,
Clustering,
DeepLearning,
Ensemble,
TimeSeries,
Other,
}
impl ModelCategory {
#[must_use]
pub const fn name(&self) -> &'static str {
match self {
Self::Regression => "Regression",
Self::Classification => "Classification",
Self::Clustering => "Clustering",
Self::DeepLearning => "Deep Learning",
Self::Ensemble => "Ensemble",
Self::TimeSeries => "Time Series",
Self::Other => "Other",
}
}
}
impl fmt::Display for ModelCategory {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.name())
}
}
include!("index.rs");