Skip to main content

hexz_store/
remote.rs

1//! Transport trait for remote archive storage.
2//!
3//! Abstracts over S3, HTTP, or other remote backends so that CLI push/pull
4//! logic is transport-agnostic.
5
6use hexz_common::{Error, Result};
7use std::io::{Error as IoError, ErrorKind};
8use std::path::Path;
9
10/// Metadata about an archive on a remote.
11#[derive(Debug, Clone)]
12pub struct RemoteArchiveInfo {
13    /// File name (e.g. `"v2.hxz"`).
14    pub name: String,
15    /// Size in bytes.
16    pub size: u64,
17}
18
19/// Transport interface for uploading/downloading archives to/from a remote.
20pub trait RemoteTransport: Send + Sync {
21    /// List all `.hxz` archives on the remote.
22    fn list_archives(&self) -> Result<Vec<RemoteArchiveInfo>>;
23
24    /// Upload a local file to the remote under `remote_name`.
25    fn upload(&self, local_path: &Path, remote_name: &str) -> Result<()>;
26
27    /// Download an archive from the remote to a local path.
28    fn download(&self, remote_name: &str, local_path: &Path) -> Result<()>;
29
30    /// Check whether an archive exists on the remote.
31    fn exists(&self, remote_name: &str) -> Result<bool>;
32}
33
34/// Connect to a remote given its URL, returning the appropriate transport.
35///
36/// Currently supports `s3://bucket/prefix` URLs. HTTP support is planned.
37pub fn connect(url: &str) -> Result<Box<dyn RemoteTransport>> {
38    if url.starts_with("s3://") {
39        #[cfg(feature = "s3")]
40        {
41            let remote = crate::s3::remote::S3Remote::connect(url)?;
42            return Ok(Box::new(remote));
43        }
44        #[cfg(not(feature = "s3"))]
45        {
46            return Err(Error::Io(IoError::new(
47                ErrorKind::Unsupported,
48                "S3 support not compiled in (missing feature \"s3\")",
49            )));
50        }
51    }
52
53    if url.starts_with("http://") || url.starts_with("https://") {
54        return Err(Error::Io(IoError::new(
55            ErrorKind::Unsupported,
56            "HTTP remotes are not yet supported",
57        )));
58    }
59
60    Err(Error::Io(IoError::new(
61        ErrorKind::InvalidInput,
62        format!("Unsupported remote URL scheme: {url}"),
63    )))
64}