use async-fs for http_source
This commit is contained in:
parent
5e9f05c4b9
commit
0f292de212
@ -38,12 +38,12 @@ impl HttpSourceAssetReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// See [`crate::io::get_meta_path`]
|
/// See [`crate::io::get_meta_path`]
|
||||||
fn make_meta_uri(&self, path: &Path) -> Option<PathBuf> {
|
fn make_meta_uri(&self, path: &Path) -> PathBuf {
|
||||||
let mut uri = self.make_uri(path);
|
let mut uri = self.make_uri(path);
|
||||||
let mut extension = path.extension()?.to_os_string();
|
let mut extension = path.extension().unwrap_or_default().to_os_string();
|
||||||
extension.push(".meta");
|
extension.push(".meta");
|
||||||
uri.set_extension(extension);
|
uri.set_extension(extension);
|
||||||
Some(uri)
|
uri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ async fn get(path: PathBuf) -> Result<Box<dyn Reader>, AssetReaderError> {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
#[cfg(feature = "http_source_cache")]
|
#[cfg(feature = "http_source_cache")]
|
||||||
if let Some(data) = http_asset_cache::try_load_from_cache(str_path)? {
|
if let Some(data) = http_asset_cache::try_load_from_cache(str_path).await? {
|
||||||
return Ok(Box::new(VecReader::new(data)));
|
return Ok(Box::new(VecReader::new(data)));
|
||||||
}
|
}
|
||||||
use ureq::Agent;
|
use ureq::Agent;
|
||||||
@ -87,7 +87,7 @@ async fn get(path: PathBuf) -> Result<Box<dyn Reader>, AssetReaderError> {
|
|||||||
reader.read_to_end(&mut buffer)?;
|
reader.read_to_end(&mut buffer)?;
|
||||||
|
|
||||||
#[cfg(feature = "http_source_cache")]
|
#[cfg(feature = "http_source_cache")]
|
||||||
http_asset_cache::save_to_cache(str_path, &buffer)?;
|
http_asset_cache::save_to_cache(str_path, &buffer).await?;
|
||||||
|
|
||||||
Ok(Box::new(VecReader::new(buffer)))
|
Ok(Box::new(VecReader::new(buffer)))
|
||||||
}
|
}
|
||||||
@ -119,12 +119,8 @@ impl AssetReader for HttpSourceAssetReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn read_meta<'a>(&'a self, path: &'a Path) -> Result<Box<dyn Reader>, AssetReaderError> {
|
async fn read_meta<'a>(&'a self, path: &'a Path) -> Result<Box<dyn Reader>, AssetReaderError> {
|
||||||
match self.make_meta_uri(path) {
|
let uri = self.make_meta_uri(path);
|
||||||
Some(uri) => get(uri).await,
|
get(uri).await
|
||||||
None => Err(AssetReaderError::NotFound(
|
|
||||||
"source path has no extension".into(),
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn is_directory<'a>(&'a self, _path: &'a Path) -> Result<bool, AssetReaderError> {
|
async fn is_directory<'a>(&'a self, _path: &'a Path) -> Result<bool, AssetReaderError> {
|
||||||
@ -147,11 +143,13 @@ mod http_asset_cache {
|
|||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::hash::{Hash, Hasher};
|
use core::hash::{Hash, Hasher};
|
||||||
|
use futures_lite::AsyncWriteExt;
|
||||||
use std::collections::hash_map::DefaultHasher;
|
use std::collections::hash_map::DefaultHasher;
|
||||||
use std::fs::{self, File};
|
use std::io;
|
||||||
use std::io::{self, Read, Write};
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use crate::io::Reader;
|
||||||
|
|
||||||
const CACHE_DIR: &str = ".http-asset-cache";
|
const CACHE_DIR: &str = ".http-asset-cache";
|
||||||
|
|
||||||
fn url_to_hash(url: &str) -> String {
|
fn url_to_hash(url: &str) -> String {
|
||||||
@ -160,28 +158,28 @@ mod http_asset_cache {
|
|||||||
std::format!("{:x}", hasher.finish())
|
std::format!("{:x}", hasher.finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_load_from_cache(url: &str) -> Result<Option<Vec<u8>>, io::Error> {
|
pub async fn try_load_from_cache(url: &str) -> Result<Option<Vec<u8>>, io::Error> {
|
||||||
let filename = url_to_hash(url);
|
let filename = url_to_hash(url);
|
||||||
let cache_path = PathBuf::from(CACHE_DIR).join(&filename);
|
let cache_path = PathBuf::from(CACHE_DIR).join(&filename);
|
||||||
|
|
||||||
if cache_path.exists() {
|
if cache_path.exists() {
|
||||||
let mut file = File::open(&cache_path)?;
|
let mut file = async_fs::File::open(&cache_path).await?;
|
||||||
let mut buffer = Vec::new();
|
let mut buffer = Vec::new();
|
||||||
file.read_to_end(&mut buffer)?;
|
file.read_to_end(&mut buffer).await?;
|
||||||
Ok(Some(buffer))
|
Ok(Some(buffer))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save_to_cache(url: &str, data: &[u8]) -> Result<(), io::Error> {
|
pub async fn save_to_cache(url: &str, data: &[u8]) -> Result<(), io::Error> {
|
||||||
let filename = url_to_hash(url);
|
let filename = url_to_hash(url);
|
||||||
let cache_path = PathBuf::from(CACHE_DIR).join(&filename);
|
let cache_path = PathBuf::from(CACHE_DIR).join(&filename);
|
||||||
|
|
||||||
fs::create_dir_all(CACHE_DIR).ok();
|
async_fs::create_dir_all(CACHE_DIR).await.ok();
|
||||||
|
|
||||||
let mut cache_file = File::create(&cache_path)?;
|
let mut cache_file = async_fs::File::create(&cache_path).await?;
|
||||||
cache_file.write_all(data)?;
|
cache_file.write_all(data).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -218,7 +216,6 @@ mod tests {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
HttpSourceAssetReader::Http
|
HttpSourceAssetReader::Http
|
||||||
.make_meta_uri(Path::new("example.com/favicon.png"))
|
.make_meta_uri(Path::new("example.com/favicon.png"))
|
||||||
.expect("cannot create meta uri")
|
|
||||||
.to_str()
|
.to_str()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
"http://example.com/favicon.png.meta"
|
"http://example.com/favicon.png.meta"
|
||||||
@ -230,7 +227,6 @@ mod tests {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
HttpSourceAssetReader::Https
|
HttpSourceAssetReader::Https
|
||||||
.make_meta_uri(Path::new("example.com/favicon.png"))
|
.make_meta_uri(Path::new("example.com/favicon.png"))
|
||||||
.expect("cannot create meta uri")
|
|
||||||
.to_str()
|
.to_str()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
"https://example.com/favicon.png.meta"
|
"https://example.com/favicon.png.meta"
|
||||||
@ -240,8 +236,11 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn make_https_without_extension_meta_uri() {
|
fn make_https_without_extension_meta_uri() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
HttpSourceAssetReader::Https.make_meta_uri(Path::new("example.com/favicon")),
|
HttpSourceAssetReader::Https
|
||||||
None
|
.make_meta_uri(Path::new("example.com/favicon"))
|
||||||
|
.to_str()
|
||||||
|
.unwrap(),
|
||||||
|
"https://example.com/favicon.meta"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,9 +14,7 @@ fn main() {
|
|||||||
|
|
||||||
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
commands.spawn(Camera2d);
|
commands.spawn(Camera2d);
|
||||||
|
let url = "https://raw.githubusercontent.com/bevyengine/bevy/refs/heads/main/assets/branding/bevy_bird_dark.png";
|
||||||
commands.spawn(
|
|
||||||
// Simply use a url where you would normally use an asset folder relative path
|
// Simply use a url where you would normally use an asset folder relative path
|
||||||
Sprite::from_image(asset_server.load("https://raw.githubusercontent.com/bevyengine/bevy/refs/heads/main/assets/branding/bevy_bird_dark.png"))
|
commands.spawn(Sprite::from_image(asset_server.load(url)));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user