Add cloud.rs for cloud input

This commit is contained in:
2026-03-19 00:32:44 +08:00
parent f5a117c878
commit 4e6db3fa21

77
src/input/cloud.rs Normal file
View File

@@ -0,0 +1,77 @@
//! 雲端輸入
use anyhow::Result;
#[derive(Debug, Clone)]
pub enum CloudSource {
S3 {
bucket: String,
key: String,
region: Option<String>,
},
Http {
url: String,
headers: Vec<(String, String)>,
},
}
impl CloudSource {
pub fn from_s3_url(url: &str) -> Result<Self> {
let parsed = url::Url::parse(url)?;
if parsed.scheme() != "s3" {
anyhow::bail!("Not an S3 URL");
}
let bucket = parsed.host_str().unwrap_or("").to_string();
let key = parsed.path().trim_start_matches('/').to_string();
Ok(Self::S3 {
bucket,
key,
region: None,
})
}
pub fn from_http_url(url: &str) -> Self {
Self::Http {
url: url.to_string(),
headers: Vec::new(),
}
}
}
pub struct CloudInput {
source: Option<CloudSource>,
}
impl CloudInput {
pub fn new() -> Self {
Self { source: None }
}
pub fn open(&mut self, url: &str) -> Result<CloudSource> {
let source = if url.starts_with("s3://") {
CloudSource::from_s3_url(url)?
} else if url.starts_with("http://") || url.starts_with("https://") {
CloudSource::from_http_url(url)
} else {
anyhow::bail!("Unsupported URL scheme");
};
self.source = Some(source.clone());
Ok(source)
}
pub fn get_stream_url(&self) -> Option<String> {
match &self.source {
Some(CloudSource::S3 { bucket, key, .. }) => {
Some(format!("https://{}.s3.amazonaws.com/{}", bucket, key))
}
Some(CloudSource::Http { url, .. }) => {
Some(url.clone())
}
None => None,
}
}
}