Files
Genarrative/server-rs/crates/platform-hyper3d/src/response/downloads.rs
2026-05-26 13:18:13 +08:00

68 lines
2.4 KiB
Rust

use serde_json::Value;
pub(crate) fn extract_download_files(
payload: &Value,
) -> Vec<shared_contracts::hyper3d::Hyper3dDownloadFilePayload> {
let mut files = Vec::new();
collect_download_files(payload, &mut files);
let mut deduped = Vec::new();
for file in files {
if !deduped.iter().any(
|entry: &shared_contracts::hyper3d::Hyper3dDownloadFilePayload| entry.url == file.url,
) {
deduped.push(file);
}
}
deduped
}
fn collect_download_files(
value: &Value,
output: &mut Vec<shared_contracts::hyper3d::Hyper3dDownloadFilePayload>,
) {
match value {
Value::Object(object) => {
let maybe_url = object
.get("url")
.or_else(|| object.get("download_url"))
.or_else(|| object.get("downloadUrl"))
.or_else(|| object.get("file_url"))
.or_else(|| object.get("fileUrl"))
.or_else(|| object.get("signed_url"))
.or_else(|| object.get("signedUrl"))
.or_else(|| object.get("presigned_url"))
.or_else(|| object.get("presignedUrl"))
.and_then(Value::as_str)
.map(str::trim)
.filter(|value| value.starts_with("http://") || value.starts_with("https://"));
if let Some(url) = maybe_url {
let name = object
.get("name")
.or_else(|| object.get("file_name"))
.or_else(|| object.get("filename"))
.or_else(|| object.get("fileName"))
.or_else(|| object.get("display_name"))
.or_else(|| object.get("displayName"))
.and_then(Value::as_str)
.map(str::trim)
.filter(|value| !value.is_empty())
.unwrap_or("model")
.to_string();
output.push(shared_contracts::hyper3d::Hyper3dDownloadFilePayload {
name,
url: url.to_string(),
});
}
for nested in object.values() {
collect_download_files(nested, output);
}
}
Value::Array(items) => {
for item in items {
collect_download_files(item, output);
}
}
_ => {}
}
}