use rocket::response::{Response, Responder};
use rocket::http::{Status, ContentType};
use rocket::request::Request;
use rocket::response::Body;
use std::result;
use std::sync::Arc;
use std::path::{PathBuf, Path};
use in_memory_file::InMemoryFile;
use concurrent_hashmap::Accessor;
use std::fmt::{Formatter, Debug};
use std::fmt;
pub struct NamedInMemoryFile<'a> {
pub(crate) path: PathBuf,
pub(crate) file: Arc<Accessor<'a, PathBuf, InMemoryFile>>,
}
impl<'a> Debug for NamedInMemoryFile<'a> {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
write!(fmt, "path: {:?}, file: {:?}", self.path, self.file.get())
}
}
impl<'a> NamedInMemoryFile<'a> {
pub(crate) fn new<P: AsRef<Path>>(path: P, m: Accessor<'a, PathBuf, InMemoryFile>) -> NamedInMemoryFile<'a> {
NamedInMemoryFile {
path: path.as_ref().to_path_buf(),
file: Arc::new(m),
}
}
}
impl<'a> Responder<'a> for NamedInMemoryFile<'a> {
fn respond_to(self, _: &Request) -> result::Result<Response<'a>, Status> {
let mut response = Response::new();
if let Some(ext) = self.path.extension() {
if let Some(ct) = ContentType::from_extension(&ext.to_string_lossy()) {
response.set_header(ct);
}
}
unsafe {
let cloned_wrapper: *const Accessor<'a, PathBuf, InMemoryFile> = Arc::into_raw(self.file);
response.set_raw_body( Body::Sized((*cloned_wrapper).get().bytes.as_slice(), (*cloned_wrapper).get().stats.size as u64) );
let _ = Arc::from_raw(cloned_wrapper); }
Ok(response)
}
}