use std::collections::BTreeMap;
use serde::{Deserialize, Serialize};
use crate::crate_info::{CrateId, FeatureSet};
use crate::platform::{Profile, RustcVersion, Target};
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, utoipa::ToSchema)]
#[serde(rename_all = "kebab-case")]
pub enum RustCrateType {
Lib,
Rlib,
Dylib,
Cdylib,
Staticlib,
ProcMacro,
}
impl Ord for RustCrateType {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.as_str().cmp(other.as_str())
}
}
impl PartialOrd for RustCrateType {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl RustCrateType {
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Lib => "lib",
Self::Rlib => "rlib",
Self::Dylib => "dylib",
Self::Cdylib => "cdylib",
Self::Staticlib => "staticlib",
Self::ProcMacro => "proc-macro",
}
}
}
#[derive(
Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, utoipa::ToSchema,
)]
pub enum ArtifactKind {
Rlib,
Dylib,
ProcMacro,
}
impl ArtifactKind {
#[must_use]
pub const fn as_str(&self) -> &str {
match self {
Self::Rlib => "rlib",
Self::Dylib => "dylib",
Self::ProcMacro => "proc-macro",
}
}
#[must_use]
pub fn parse(value: &str) -> Option<Self> {
[Self::Rlib, Self::Dylib, Self::ProcMacro]
.into_iter()
.find(|kind| kind.as_str() == value)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ArtifactKey {
pub crate_id: CrateId,
pub features: FeatureSet,
pub crate_types: Vec<RustCrateType>,
pub target: Target,
pub rustc_version: RustcVersion,
pub profile: Profile,
pub kind: ArtifactKind,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ArtifactMetadata {
pub key: ArtifactKey,
pub rlib_sha256: String,
pub rmeta_sha256: Option<String>,
pub has_native_artifacts: bool,
pub built_at: String,
pub builder_run_id: u64,
pub stow_version: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct NativeArtifacts {
pub static_libs: Vec<NativeLib>,
pub cargo_directives: Vec<String>,
pub dep_env_vars: BTreeMap<String, String>,
pub out_dir_files: Vec<OutDirFile>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct NativeLib {
pub name: String,
pub bytes_sha256: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct OutDirFile {
pub relative_path: String,
pub sha256: String,
}
#[cfg(test)]
mod tests {
use super::{ArtifactKind, RustCrateType};
#[test]
fn artifact_kind_round_trips_through_its_wire_string() {
for kind in [
ArtifactKind::Rlib,
ArtifactKind::Dylib,
ArtifactKind::ProcMacro,
] {
assert_eq!(ArtifactKind::parse(kind.as_str()), Some(kind));
}
assert_eq!(ArtifactKind::parse("proc_macro"), None);
assert_eq!(ArtifactKind::parse("Rlib"), None);
}
#[test]
fn crate_type_ordering_matches_wire_strings() {
let mut all = [
RustCrateType::Lib,
RustCrateType::Rlib,
RustCrateType::Dylib,
RustCrateType::Cdylib,
RustCrateType::Staticlib,
RustCrateType::ProcMacro,
];
all.sort();
let strings: Vec<&str> = all.iter().map(RustCrateType::as_str).collect();
let mut sorted_strings = strings.clone();
sorted_strings.sort_unstable();
assert_eq!(
strings, sorted_strings,
"producers sort crate_types with Ord while validators compare wire strings; the orders must agree"
);
}
}