use std::io;
use std::marker::PhantomData;
use std::path::{Path, PathBuf};
use futures::{Async, Future, Poll};
use super::Exporter;
pub struct FileExporter<P>(PhantomData<P>);
unsafe impl<P> Send for FileExporter<P> {}
unsafe impl<P> Sync for FileExporter<P> {}
impl<P> Default for FileExporter<P> {
#[inline(always)]
fn default() -> Self {
FileExporter(PhantomData)
}
}
impl<P> FileExporter<P> {
#[inline(always)]
pub fn new() -> Self {
Self::default()
}
}
impl<P> Exporter for FileExporter<P>
where
P: Send + Clone + AsRef<Path>,
{
type Input = Vec<u8>;
type Path = P;
type Options = ();
type Error = io::Error;
type Future = FileSaveFuture;
#[inline(always)]
fn export(&self, input: Self::Input, path: Self::Path, _: Self::Options) -> Self::Future {
FileSaveFuture {
input: input,
path: path.as_ref().to_path_buf(),
}
}
}
pub struct FileSaveFuture {
input: Vec<u8>,
path: PathBuf,
}
impl Future for FileSaveFuture {
type Item = ();
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::Write;
if let Some(parent) = self.path.parent() {
fs::create_dir_all(parent)?;
}
let mut file = fs::File::create(&self.path)?;
file.write_all(&self.input)?;
Ok(Async::Ready(()))
}
#[cfg(target_os = "android")]
#[inline]
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
Err(Error::new(
ErrorKind::PermissionDenied,
"android assets can not be exportd",
))
}
}
#[test]
fn test_export() {
use futures::Future;
let file_exporter = FileExporter::new();
match file_exporter
.export(Vec::new(), "assets/empty.txt", ())
.wait()
{
Ok(_) => (),
Err(e) => panic!("{:?}", e),
}
}