2023-10-18 02:04:25 +00:00
|
|
|
use base64::Engine;
|
|
|
|
use thiserror::Error;
|
|
|
|
use std::io;
|
|
|
|
|
|
|
|
#[derive(Error, Debug)]
|
|
|
|
pub enum UriReadError {
|
|
|
|
#[error("IOError: '{0}'")]
|
|
|
|
IoError(io::Error),
|
|
|
|
|
|
|
|
// From is implemented for this field in each loader module
|
|
|
|
#[error("Base64 decoding error: '{0}'")]
|
|
|
|
Base64Decode(base64::DecodeError),
|
|
|
|
|
|
|
|
#[error("Some data was missing from the uri")]
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Read a buffer's uri string into a byte buffer.
|
|
|
|
///
|
|
|
|
/// * `containing_path`: The path of the containing folder of the buffers "parent",
|
|
|
|
/// the parent being where this buffer is defined in,
|
2023-10-22 02:19:34 +00:00
|
|
|
/// i.e. parent="resources/models/player.gltf", containing="resource/models"
|
2023-10-18 02:04:25 +00:00
|
|
|
pub(crate) fn gltf_read_buffer_uri(containing_path: &str, uri: &str) -> Result<Vec<u8>, UriReadError> {
|
2023-10-22 02:19:34 +00:00
|
|
|
if let Some((mime, data)) = uri.strip_prefix("data")
|
|
|
|
.and_then(|uri| uri.split_once(",")) {
|
|
|
|
let (_mime, is_base64) = match mime.strip_suffix(";base64") {
|
|
|
|
Some(mime) => (mime, true),
|
|
|
|
None => (mime, false),
|
|
|
|
};
|
|
|
|
|
|
|
|
if is_base64 {
|
|
|
|
base64::engine::general_purpose::STANDARD.decode(data)
|
|
|
|
.map_err(|e| UriReadError::Base64Decode(e))
|
|
|
|
} else {
|
|
|
|
Ok(data.as_bytes().to_vec())
|
|
|
|
}
|
2023-10-18 02:04:25 +00:00
|
|
|
} else {
|
2023-10-22 02:19:34 +00:00
|
|
|
let full_path = format!("{containing_path}/{uri}");
|
2023-10-18 02:04:25 +00:00
|
|
|
std::fs::read(&full_path).map_err(|e| UriReadError::IoError(e))
|
|
|
|
}
|
|
|
|
}
|