use std::collections::BTreeMap;
use serde::{Deserialize, Serialize};
use crate::{manifest::Component, plan::PlanKey, resolve::Intent, toolchain::Patch};
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct PublicationId(String);
impl PublicationId {
pub fn generate() -> Self {
Self(crate::utils::opaque_id())
}
pub fn as_str(&self) -> &str {
&self.0
}
}
impl std::fmt::Display for PublicationId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.0)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "kebab-case")]
pub enum PublicationRef {
Managed {
id: PublicationId,
plan_key: PlanKey,
target: String,
},
NeedsReinstall,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum RealizedMethod {
Prebuilt,
Cargo,
Extracted,
None,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Output {
pub path: std::path::PathBuf,
pub owner: String,
pub mode: u32,
pub realized: RealizedMethod,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub digest: Option<crate::artifact::Digest>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Receipt {
pub publication_id: PublicationId,
pub plan_key: PlanKey,
pub target: String,
pub channel: semver::Version,
pub outputs: Vec<Output>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Installation {
pub channel: semver::Version,
pub intent: Intent,
pub components: Vec<Component>,
pub publication: PublicationRef,
pub installed_at: i64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub midenup_version: Option<semver::Version>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub patches: BTreeMap<String, Patch>,
}
impl Installation {
pub fn is_managed(&self) -> bool {
matches!(self.publication, PublicationRef::Managed { .. })
}
pub fn as_channel(&self) -> crate::manifest::Channel {
crate::manifest::Channel::new(self.channel.clone(), self.components.clone())
}
}