diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | codegen/src/lib.rs | 41 | ||||
-rw-r--r-- | example/Cargo.toml | 6 | ||||
-rw-r--r-- | example/build.rs | 13 | ||||
-rw-r--r-- | lib/src/lib.rs | 13 |
5 files changed, 58 insertions, 17 deletions
@@ -13,7 +13,7 @@ Include a directory in your Rust binary, e.g. static files for your web server o * [x] Use [rust-phf](https://github.com/sfackler/rust-phf) for efficient lookup * [x] Wrapping API around the phf map, to abstract away additional features * [x] Compression, with optional crate "flate2" -* [ ] Reading from source files for debug builds +* [x] Reading from source files for debug builds ## Example diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index e8a6475..2cd9392 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -2,7 +2,7 @@ extern crate walkdir; extern crate phf_codegen; extern crate flate2; -use std::{fmt, env, io}; +use std::{env, fmt, io}; use std::borrow::{Borrow, Cow}; use std::collections::HashMap; use std::fs::{self, File}; @@ -13,10 +13,11 @@ use walkdir::WalkDir; use flate2::FlateWriteExt; -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum Compression { None, Gzip, + Passthrough, } impl fmt::Display for Compression { @@ -24,6 +25,7 @@ impl fmt::Display for Compression { match *self { Compression::None => fmt.write_str("None"), Compression::Gzip => fmt.write_str("Gzip"), + Compression::Passthrough => panic!("Should not be called"), } } } @@ -31,12 +33,14 @@ impl fmt::Display for Compression { pub struct IncludeDir { files: HashMap<String, (Compression, PathBuf)>, name: String, + passthrough: bool, } pub fn start(static_name: &str) -> IncludeDir { IncludeDir { files: HashMap::new(), name: static_name.to_owned(), + passthrough: false, } } @@ -51,6 +55,12 @@ fn as_key(path: &str) -> Cow<str> { } impl IncludeDir { + /// Don't include any data, but read from the source directory instead. + pub fn passthrough(&mut self) -> &mut IncludeDir { + self.passthrough = true; + self + } + /// Add a single file to the binary. /// With Gzip compression, the file will be encoded to OUT_DIR first. /// For chaining, it's not sensible to return a Result. If any to-be-included @@ -65,7 +75,13 @@ impl IncludeDir { /// This function panics when CARGO_MANIFEST_DIR or OUT_DIR are not defined. pub fn add_file<P: AsRef<Path>>(&mut self, path: P, comp: Compression) -> io::Result<()> { let key = path.as_ref().to_string_lossy(); + match comp { + c if self.passthrough || c == Compression::Passthrough => { + self.files.insert(as_key(key.borrow()).into_owned(), + (Compression::Passthrough, PathBuf::new())); + + } Compression::None => { self.files.insert(as_key(key.borrow()).into_owned(), (comp, path.as_ref().clone().to_owned())); @@ -85,6 +101,7 @@ impl IncludeDir { self.files.insert(as_key(key.borrow()).into_owned(), (comp, out_path.to_owned())); } + _ => unreachable!(), } Ok(()) } @@ -122,17 +139,23 @@ impl IncludeDir { \tfiles: ", self.name)); - let entries: Vec<_> = self.files //accumulate_entries() + let entries: Vec<_> = self.files .iter() .map(|(name, &(ref comp, ref path))| { let include_path = format!("{}", base_path.join(path).display()); - let code = format!("(Compression::{}, \ - include_bytes!(\"{}\") as &'static \ - [u8])", - comp, - as_key(&include_path)); - (as_key(&name).into_owned(), code) + if comp == &Compression::Passthrough { + (as_key(&name).into_owned(), + "(Compression::Passthrough, &[] as &'static [u8])" + .to_owned()) + } else { + let code = format!("(Compression::{}, \ + include_bytes!(\"{}\") as &'static \ + [u8])", + comp, + as_key(&include_path)); + (as_key(&name).into_owned(), code) + } }) .collect(); let mut map: phf_codegen::Map<&str> = phf_codegen::Map::new(); diff --git a/example/Cargo.toml b/example/Cargo.toml index c7c6496..3d3cbd5 100644 --- a/example/Cargo.toml +++ b/example/Cargo.toml @@ -8,7 +8,9 @@ publish = false [dependencies] phf = "0.7.12" -includedir = "0.2.0" +# includedir = "0.2.0" +includedir = { path = "../lib" } [build-dependencies] -includedir_codegen = "0.2.0" +# includedir_codegen = "0.2.0" +includedir_codegen = { path = "../codegen" } diff --git a/example/build.rs b/example/build.rs index fb23001..c13f035 100644 --- a/example/build.rs +++ b/example/build.rs @@ -1,10 +1,15 @@ extern crate includedir_codegen; +use std::env; + use includedir_codegen::Compression; fn main() { - includedir_codegen::start("FILES") - .dir("data", Compression::Gzip) - .build("data.rs") - .unwrap(); + let mut cg = includedir_codegen::start("FILES"); + if env::var("PASSTHROUGH").is_ok() { + cg.passthrough(); + } + cg.dir("data", Compression::Gzip) + .build("data.rs") + .unwrap(); } diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 20078a2..ce1e2ec 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -4,7 +4,8 @@ extern crate phf; extern crate flate2; use std::borrow::{Borrow, Cow}; -use std::io::{self, Cursor, Error, ErrorKind, Read}; +use std::io::{self, BufReader, Cursor, Error, ErrorKind, Read}; +use std::fs::File; #[cfg(feature = "flate2")] use flate2::FlateReadExt; @@ -12,6 +13,7 @@ use flate2::FlateReadExt; pub enum Compression { None, Gzip, + Passthrough, } /// Runtime access to the included files @@ -50,6 +52,12 @@ impl Files { } #[cfg(not(feature = "flate2"))] Compression::Gzip => panic!("Feature 'flate2' not enabled"), + Compression::Passthrough => { + let mut r = BufReader::new(try!(File::open(path))); + 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")), @@ -66,6 +74,9 @@ impl Files { Compression::Gzip => Ok(Box::new(try!(Cursor::new(b.1).gz_decode()))), #[cfg(not(feature = "flate2"))] Compression::Gzip => panic!("Feature 'flate2' not enabled"), + Compression::Passthrough => { + Ok(Box::new(BufReader::new(try!(File::open(path))))) + } } } None => Err(Error::new(ErrorKind::NotFound, "Key not found")), |