diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Cargo.toml | 17 | ||||
-rw-r--r-- | lib/src/lib.rs | 65 |
2 files changed, 82 insertions, 0 deletions
diff --git a/lib/Cargo.toml b/lib/Cargo.toml new file mode 100644 index 0000000..aa82ad8 --- /dev/null +++ b/lib/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "includedir" +description = "Include a whole directory tree at compile time! - Runtime part" +keywords = ["include", "tree", "directory", "build", "static"] +version = "0.1.1" +authors = ["Till Höppner <till@hoeppner.ws>"] +license = "MIT" +homepage = "https://github.com/tilpner/includedir" +repository = "https://github.com/tilpner/includedir" + +[features] +default = ["flate2"] + +[dependencies] +phf = "0.7.12" + +flate2 = { version = "*", optional = true } diff --git a/lib/src/lib.rs b/lib/src/lib.rs new file mode 100644 index 0000000..666c727 --- /dev/null +++ b/lib/src/lib.rs @@ -0,0 +1,65 @@ +extern crate phf; +extern crate flate2; + +use std::borrow::{Borrow, Cow}; +use std::io::{self, Cursor, Error, ErrorKind, Read}; + +use flate2::FlateReadExt; + +pub enum Compression { + None, + Gzip, +} + +/// Runtime access to the included files +pub struct Files { + /// **Do not access this field, it is only public to allow for code generation!** + pub files: phf::Map<&'static str, (Compression, &'static [u8])>, +} + +#[cfg(windows)] +fn as_key(path: &str) -> Cow<str> { + Cow::Owned(path.replace("\\", "/")) +} + +#[cfg(not(windows))] +fn as_key(path: &str) -> Cow<str> { + Cow::Borrowed(path) +} + +impl Files { + pub fn available(&self, path: &str) -> bool { + self.files.contains_key(path) + } + + pub fn get(&self, path: &str) -> io::Result<Cow<'static, [u8]>> { + let key = as_key(path); + match self.files.get(key.borrow() as &str) { + Some(b) => { + match b.0 { + Compression::None => Ok(Cow::Borrowed(b.1)), + Compression::Gzip => { + let mut r = try!(Cursor::new(b.1).gz_decode()); + let mut v = Vec::new(); + try!(r.read_to_end(&mut v)); + Ok(Cow::Owned(v)) + } + } + } + None => Err(Error::new(ErrorKind::NotFound, "Key not found")), + } + } + + pub fn read(&self, path: &str) -> io::Result<Box<Read>> { + let key = as_key(path); + match self.files.get(key.borrow() as &str) { + Some(b) => { + match b.0 { + Compression::None => Ok(Box::new(Cursor::new(b.1))), + Compression::Gzip => Ok(Box::new(try!(Cursor::new(b.1).gz_decode()))), + } + } + None => Err(Error::new(ErrorKind::NotFound, "Key not found")), + } + } +} |