mod bundle;
mod graph;
mod workspace;
use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize};
use wyrd_spec::{error::WyrdError, reference::CardRef};
pub use wyrd_spec::registry::{
BundleArtifactManifest, BundleCardManifest, BundleManifest, BundleMode,
};
use crate::cards::{CardSelector, RegistryContext};
use self::{bundle::BundleWriter, workspace::BundleWorkspace};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PullSummary {
pub root: CardRef,
pub destination: PathBuf,
pub mode: BundleMode,
pub card_count: usize,
pub artifact_count: usize,
pub downloaded_artifact_count: usize,
}
#[derive(Clone)]
pub struct CardGraphPuller {
context: RegistryContext,
}
impl CardGraphPuller {
#[must_use]
pub fn new(context: RegistryContext) -> Self {
Self { context }
}
pub async fn pull(
&self,
selector: &CardSelector,
destination: &Path,
mode: BundleMode,
) -> Result<PullSummary, WyrdError> {
let graph = self.resolve_graph(selector).await?;
let workspace = BundleWorkspace::prepare(destination)?;
let write_result = {
let writer = BundleWriter::new(&self.context, workspace.staging(), mode);
writer.write(&graph).await
};
let stats = match write_result {
Ok(stats) => stats,
Err(error) => {
workspace.abort();
return Err(error);
}
};
if let Err(error) = workspace.publish() {
workspace.abort();
return Err(error);
}
Ok(PullSummary {
root: graph.root,
destination: workspace.destination().to_path_buf(),
card_count: graph.cards.len(),
artifact_count: stats.artifact_count,
downloaded_artifact_count: stats.downloaded_artifact_count,
mode,
})
}
}
#[cfg(test)]
mod tests {
use super::BundleMode;
#[test]
fn bundle_mode_uses_bundle_wire_values() {
assert_eq!(
serde_json::to_string(&BundleMode::MetadataOnly).expect("metadata mode serializes"),
"\"metadata\""
);
assert_eq!(
serde_json::to_string(&BundleMode::Complete).expect("complete mode serializes"),
"\"complete\""
);
}
}