use async_trait::async_trait;
use auto_impl::auto_impl;
use chrono::{DateTime, Utc};
use indexmap::IndexMap;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use thiserror::Error;
use url::Url;
#[cfg(feature = "http")]
pub mod http;
#[async_trait]
#[auto_impl(&, Arc)]
pub trait CargoClient: Send + Sync {
async fn get_crate(&self, req: GetCrateRequestView<'_>) -> Result<ExtendedCrate, GetCrateError>;
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Error)]
pub enum GetCrateError {
#[error("failed to send `GetCrate` request: {0}")]
Send(String),
#[error("failed to receive `GetCrate` response: {0}")]
Receive(String),
#[error("crate not found")]
NotFound,
#[error("unexpected `GetCrate` error: {0}")]
Other(String),
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct GetCrateRequest<Str = String> {
pub name: Str,
}
pub type GetCrateRequestView<'req> = GetCrateRequest<&'req str>;
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ExtendedCrate {
pub categories: Vec<Category>,
#[serde(rename = "crate")]
pub krate: Crate,
pub keywords: Vec<Keyword>,
pub versions: Vec<CrateVersion>,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Category {
pub category: String,
pub crates_cnt: u64,
pub created_at: DateTime<Utc>,
pub description: String,
pub id: String,
pub slug: String,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Crate {
pub categories: Vec<String>,
pub created_at: DateTime<Utc>,
pub description: String,
pub documentation: Option<Url>,
pub downloads: u64,
pub exact_match: bool,
pub homepage: Option<Url>,
pub id: String,
pub keywords: Vec<String>,
pub links: CrateLinks,
pub max_stable_version: String,
pub max_version: String,
pub name: String,
pub newest_version: String,
pub recent_downloads: Option<u64>,
pub repository: Option<Url>,
pub updated_at: DateTime<Utc>,
pub versions: Vec<u64>,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct CrateLinks {
pub owner_team: String,
pub owner_user: String,
pub owners: String,
pub reverse_dependencies: String,
pub version_downloads: String,
pub versions: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Keyword {
pub crates_cnt: u64,
pub created_at: DateTime<Utc>,
pub id: String,
pub keyword: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CrateVersion {
pub audit_actions: Vec<AuditAction>,
pub checksum: String,
#[serde(rename = "crate")]
pub krate: String,
pub crate_size: u64,
pub created_at: DateTime<Utc>,
pub dl_path: String,
pub downloads: u64,
pub features: IndexMap<String, Vec<String>>,
pub id: u64,
pub license: Option<String>,
pub links: VersionLinks,
pub num: String,
pub published_by: User,
pub readme_path: Option<String>,
pub rust_version: Option<String>,
pub updated_at: DateTime<Utc>,
pub yanked: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct AuditAction {
action: String,
time: DateTime<Utc>,
user: User,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct VersionLinks {
pub authors: String,
pub dependencies: String,
pub version_downloads: String,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct User {
pub avatar: Option<Url>,
pub email: Option<String>,
pub id: u64,
pub kind: Option<String>,
pub login: String,
pub name: String,
pub url: Url,
}