Skip to main content

void_core/pipeline/remote/
export.rs

1//! CAR export operations for offline/sneakernet sharing.
2
3use std::path::Path;
4
5use crate::refs;
6use crate::transport::car;
7use crate::{cid, Result, VoidError};
8
9use super::push::collect_local_objects;
10use super::{ExportCarOptions, ExportCarResult};
11
12/// Export a commit and all its objects to a CAR file.
13///
14/// The CAR file can be transferred via SCP, HTTP, or any other method,
15/// then imported on a remote IPFS node with `ipfs dag import`.
16pub fn export_commit_to_car<P: AsRef<Path>>(
17    opts: ExportCarOptions,
18    output_path: P,
19) -> Result<ExportCarResult> {
20    let commit_cid = match opts.commit_cid {
21        Some(cid_str) => cid::parse(&cid_str)?,
22        None => {
23            let head_commit_cid = refs::resolve_head(&opts.ctx.paths.void_dir)?
24                .ok_or_else(|| VoidError::NotFound("HEAD".into()))?;
25            cid::from_bytes(head_commit_cid.as_bytes())?
26        }
27    };
28    let commit_cid_str = commit_cid.to_string();
29
30    let objects = collect_local_objects(&opts.ctx, &commit_cid)?;
31    let blocks_exported = car::export_car_to_file(output_path.as_ref(), &commit_cid, &objects)?;
32
33    let car_size = std::fs::metadata(output_path.as_ref())
34        .map(|m| m.len())
35        .unwrap_or(0);
36
37    Ok(ExportCarResult {
38        commit_cid: commit_cid_str,
39        car_path: output_path.as_ref().to_path_buf(),
40        blocks_exported,
41        car_size,
42    })
43}
44
45/// Export a commit to CAR and return the raw bytes (for in-memory use).
46pub fn export_commit_to_car_bytes(opts: ExportCarOptions) -> Result<(String, Vec<u8>, usize)> {
47    let commit_cid = match opts.commit_cid {
48        Some(cid_str) => cid::parse(&cid_str)?,
49        None => {
50            let head_commit_cid = refs::resolve_head(&opts.ctx.paths.void_dir)?
51                .ok_or_else(|| VoidError::NotFound("HEAD".into()))?;
52            cid::from_bytes(head_commit_cid.as_bytes())?
53        }
54    };
55    let commit_cid_str = commit_cid.to_string();
56
57    let objects = collect_local_objects(&opts.ctx, &commit_cid)?;
58    let mut car_bytes = Vec::new();
59    let blocks_exported = car::export_car(&mut car_bytes, &commit_cid, &objects)?;
60
61    Ok((commit_cid_str, car_bytes, blocks_exported))
62}