krust_asset_loader/
lib.rs1extern crate serde_json;
2#[macro_use] extern crate failure;
3
4use std::path::{Path, PathBuf};
5use std::fs;
6use std::io::{self, Read};
7use std::ffi;
8
9#[derive(Debug, Fail)]
10pub enum Error {
11 #[fail(display = "I/O error")]
12 Io(#[cause] io::Error),
13 #[fail(display = "Failed to read CString from file that contains 0")]
14 FileContainsNil,
15 #[fail(display = "Failed get executable path")]
16 FailedToGetExePath,
17}
18
19impl From<io::Error> for Error {
20 fn from(other: io::Error) -> Self {
21 Error::Io(other)
22 }
23}
24
25pub struct AssetLoader {
26 root_path: PathBuf,
27}
28
29impl AssetLoader {
30 pub fn new(rel_path: &Path) -> Result<AssetLoader, Error> {
31 let exe_file_name = ::std::env::current_exe().map_err(|_| Error::FailedToGetExePath)?;
32 let exe_path = exe_file_name.parent().ok_or(Error::FailedToGetExePath)?;
33
34 Ok(AssetLoader {
35 root_path: exe_path.join(rel_path)
36 })
37 }
38
39 pub fn load_cstring(&self, resource_name: &str) -> Result<ffi::CString, Error> {
40 let mut file = fs::File::open(
41 resource_name_to_path(&self.root_path, resource_name)
42 )?;
43
44 let mut buffer: Vec<u8> = Vec::with_capacity(
46 file.metadata()?.len() as usize + 1
47 );
48 file.read_to_end(&mut buffer)?;
49
50 if buffer.iter().find(|i| **i == 0).is_some() {
52 return Err(Error::FileContainsNil);
53 }
54
55 Ok(unsafe { ffi::CString::from_vec_unchecked(buffer) })
56 }
57
58 pub fn load_string(&self, resource_name: &str) -> PathBuf {
59 resource_name_to_path(&self.root_path, resource_name)
60 }
61
62 pub fn load_json(&self, resource_name: &str) -> serde_json::Value {
63 let mut file = fs::File::open(self.load_string(resource_name)).expect("Unable to load JSON");
64 let mut data = String::new();
65 file.read_to_string(&mut data).unwrap();
66
67 serde_json::from_str(&data).expect("JSON was not well-formatted")
68 }
69}
70
71fn resource_name_to_path(root_dir: &Path, location: &str) -> PathBuf {
72 let mut path: PathBuf = root_dir.into();
73
74 for part in location.split("/") {
75 path = path.join(part);
76 }
77
78 path
79}