use bytes::Bytes;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use ssh_key::PublicKey;
use std::time::Duration;
use strum::EnumString;
#[cfg(feature = "proptest")]
use test_strategy::Arbitrary;
use url::Url;
use uuid::Uuid;
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "proptest", derive(Arbitrary))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct TargetTriple(String);
impl TargetTriple {
pub fn arch(&self) -> &str {
self.0.split('-').nth(0).unwrap()
}
pub fn vendor(&self) -> &str {
self.0.split('-').nth(1).unwrap()
}
pub fn system(&self) -> &str {
self.0.split('-').nth(2).unwrap()
}
pub fn abi(&self) -> Option<&str> {
self.0.split('-').nth(3)
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "proptest", derive(Arbitrary))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct CrateName(String);
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CrateVersion {
krate: CrateName,
version: semver::Version,
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, EnumString)]
#[cfg_attr(feature = "proptest", derive(Arbitrary))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[strum(serialize_all = "snake_case")]
pub enum ArtifactKind {
Metadata,
Tarball,
Debian,
Coverage,
}
impl ArtifactKind {
pub fn extension(&self) -> &'static str {
match self {
Self::Metadata => "metadata.json",
Self::Tarball => "tar.gz",
Self::Debian => "deb",
Self::Coverage => "coverage.json",
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "proptest", derive(Arbitrary))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ArtifactId {
pub task: Task,
}
impl ArtifactId {
pub fn file_name(&self) -> String {
self.task.file_name()
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum ArtifactData {
Data {
bytes: Bytes,
},
Redirect {
validity: Duration,
url: Url,
},
}
impl ArtifactData {
pub fn bytes(&self) -> Option<&Bytes> {
match self {
Self::Data { bytes } => Some(bytes),
Self::Redirect { .. } => None,
}
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Builder {
pub uuid: Uuid,
pub public_key: PublicKey,
pub comment: String,
pub enabled: bool,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct TargetInfo {
pub name: String,
pub enabled: bool,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct CrateInfo {
pub name: String,
pub enabled: bool,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct VersionInfo {
pub name: String,
pub version: String,
pub checksum: String,
pub yanked: bool,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct JobInfo {
pub uuid: Uuid,
pub builder: Uuid,
pub name: String,
pub version: String,
pub triple: Option<String>,
pub url: Url,
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "proptest", derive(Arbitrary))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Task {
#[cfg_attr(feature = "proptest", strategy("[a-z]{20}"))]
pub krate: String,
#[cfg_attr(feature = "proptest", strategy("[a-z]{20}"))]
pub version: String,
#[cfg_attr(feature = "proptest", strategy(proptest::option::of("[a-z]{1,20}")))]
pub triple: Option<String>,
pub kind: ArtifactKind,
pub priority: i32,
#[cfg_attr(feature = "proptest", strategy(proptest::option::of("[a-z]{1,20}")))]
pub variant: Option<String>,
}
impl Task {
pub fn file_name(&self) -> String {
let Self {
krate,
version,
kind,
..
} = &self;
let mut name = format!("{krate}_{version}");
if let Some(triple) = &self.triple {
name.push('_');
name.push_str(triple);
}
if let Some(variant) = &self.variant {
name.push('_');
name.push_str(variant);
}
name.push('.');
name.push_str(kind.extension());
name
}
}
#[cfg(all(test, feature = "proptest"))]
mod tests {
use super::*;
use test_strategy::proptest;
#[proptest]
fn task_path_different(left: Task, right: Task) {
if left != right {
assert!(left.file_name() != right.file_name());
}
}
}