68 lines
2.4 KiB
Rust
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);
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|