use std::io;
use std::marker::PhantomData;
use std::path::{Path, PathBuf};
use futures::{Async, Future, Poll};
use super::Importer;
pub struct FileImporter<P>(PhantomData<P>);
unsafe impl<P> Send for FileImporter<P> {}
unsafe impl<P> Sync for FileImporter<P> {}
impl<P> Default for FileImporter<P> {
#[inline(always)]
fn default() -> Self {
FileImporter(PhantomData)
}
}
impl<P> FileImporter<P> {
#[inline(always)]
pub fn new() -> Self {
Self::default()
}
}
impl<P> Importer for FileImporter<P>
where
P: Clone + AsRef<Path>,
{
type Path = P;
type Options = ();
type Output = Vec<u8>;
type Error = io::Error;
type Future = FileLoadFuture;
#[inline(always)]
fn import(&self, path: Self::Path, _: Self::Options) -> Self::Future {
FileLoadFuture {
path: path.as_ref().to_path_buf(),
}
}
}
pub struct FileLoadFuture {
path: PathBuf,
}
impl Future for FileLoadFuture {
type Item = Vec<u8>;
type Error = io::Error;
#[cfg(not(target_os = "android"))]
#[inline]
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
use std::fs;
use std::io::Read;
let mut file = fs::File::open(&self.path)?;
let mut buf = Vec::new();
file.read_to_end(&mut buf)?;
Ok(Async::Ready(buf))
}
#[cfg(target_os = "android")]
#[inline]
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
use android_glue::{self, AssetError};
use std::io::{Error, ErrorKind};
match android_glue::import_asset(&*(self.path.as_ref().to_string_lossy())) {
Ok(buf) => Ok(Async::Ready(buf)),
Err(asset_error) => match asset_error {
AssetError::AssetMissing => Err(Error::new(ErrorKind::NotFound, "asset missing")),
AssetError::EmptyBuffer => Err(Error::new(ErrorKind::InvalidData, "empty buffer")),
},
}
}
}
#[test]
fn test_import() {
use futures::Future;
let file_importer = FileImporter::new();
match file_importer.import("assets/crate.jpg", ()).wait() {
Ok(_) => (),
Err(e) => panic!("{:?}", e),
}
}