use std::path::Path;
use anyhow::{Context, Result};
use crate::config::Config;
use crate::core::Node;
use crate::registry::{Registry, OPEN_RING_NAME};
use crate::util::parse_hash;
use super::import_path;
async fn resolve_target(target: &str, data_dir: &Path) -> Result<(iroh_blobs::Hash, Registry)> {
let path = std::path::PathBuf::from(target);
if path.exists() {
let cfg = Config::load_or_create(data_dir).context("loading config")?;
let node = Node::start(data_dir, cfg).await?;
let (hash, _) = import_path(&node, &path).await?;
let registry = node.registry.clone();
node.shutdown().await?;
Ok((hash, registry))
} else {
let hash = parse_hash(target)?;
let registry = Registry::open(data_dir.join("registry.redb"))?;
Ok((hash, registry))
}
}
pub async fn run_tag(
target: String,
rings: Vec<String>,
open: bool,
data_dir: &Path,
) -> Result<()> {
tokio::fs::create_dir_all(data_dir).await?;
let (hash, registry) = resolve_target(&target, data_dir).await?;
for ring in &rings {
registry.tag_file(hash, ring)?;
println!("Tagged {hash} with ring '{ring}'");
}
if open {
registry.tag_file(hash, OPEN_RING_NAME)?;
println!("Tagged {hash} as open (publicly accessible)");
}
Ok(())
}
pub async fn run_tags(target: String, data_dir: &Path) -> Result<()> {
tokio::fs::create_dir_all(data_dir).await?;
let (hash, registry) = resolve_target(&target, data_dir).await?;
let rings = registry.file_rings(hash)?;
if rings.is_empty() {
println!("{hash}: no rings (access denied to all peers)");
} else {
println!("{}: {} rings:", hash, rings.len());
for ring in &rings {
if ring.is_open() {
println!(" {} (open — publicly accessible)", ring.as_str());
} else {
println!(" {}", ring.as_str());
}
}
}
Ok(())
}