pocket-resources-0.3.2/.gitignore000066400017500001750000000000221264170525000152170ustar0000000000000000target Cargo.lock pocket-resources-0.3.2/.travis.yml000066400017500001750000000004411264170525000153450ustar0000000000000000language: rust sudo: true script: - cargo test -v --manifest-path Cargo.toml - cargo run -v --manifest-path demo/Cargo.toml after_success: - | [ $TRAVIS_BRANCH = master ] && [ $TRAVIS_PULL_REQUEST = false ] && cargo publish --token ${CRATESIO_TOKEN} pocket-resources-0.3.2/Cargo.toml000066400017500001750000000015161264170525000151700ustar0000000000000000# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g. crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] name = "pocket-resources" version = "0.3.2" authors = ["Pierre Krieger "] description = "Include resources in your applications." keywords = ["resources"] license = "MIT" repository = "https://github.com/tomaka/pocket-resources" [lib] name = "pocket_resources" path = "src/lib.rs" pocket-resources-0.3.2/Cargo.toml.orig000066400017500001750000000005021264170525000161210ustar0000000000000000[package] name = "pocket-resources" version = "0.3.2" authors = ["Pierre Krieger "] description = "Include resources in your applications." keywords = ["resources"] license = "MIT" repository = "https://github.com/tomaka/pocket-resources" [lib] name = "pocket_resources" path = "src/lib.rs" pocket-resources-0.3.2/README.md000066400017500001750000000014551264170525000145210ustar0000000000000000# Pocket-resources ## Usage See the demo crate. Tweak your Cargo.toml to use a build script: ```toml [package] # ... build = "build.rs" [build-dependencies] pocket-resources = "*" ``` Create a `build.rs` file: ```rust extern crate pocket_resources; fn main() { pocket_resources::package(&["resources"]).unwrap(); } ``` Include the resources where you want: ```rust include!(concat!(env!("OUT_DIR"), "/pocket-resources.rs")); ``` This creates a public enum named `Resource`. If you want to name it something else, or if you want it private, you should use a module. You can then load the resource directly from the enum: ```rust let data: &[u8] = Resource::PathToImagePng.load(); ``` Or load it at runtime: ```rust let data: &[u8] = Resource::from_name("path/to/image.png").unwrap().load(); ``` pocket-resources-0.3.2/src/lib.rs000066400017500001750000000156241264170525000151500ustar0000000000000000use std::ascii::AsciiExt; use std::env; use std::io; use std::io::Write; use std::fs::File; use std::iter::IntoIterator; use std::path::Path; use std::collections::HashSet; #[derive(Debug)] struct Entry { path: Vec, struct_name: String, struct_name_no_ext: String, resource_str_name: String, resource_str_name_no_ext: String, file_path: String, enum_name: String, } pub fn package<'a, I, P1, P2>(files: I) -> io::Result<()> where I: IntoIterator, P1: AsRef + 'a, P2: AsRef + 'a { let entries = files.into_iter().map(|&(ref base_dir, ref file)| { let base_dir = base_dir.as_ref(); let file = file.as_ref(); println!("cargo:rerun-if-changed={}/{}", base_dir.display(), file.display()); Entry { path: file.parent().into_iter().flat_map(|p| p.iter()).map(|val| { let val = val.to_str().expect("Cannot process non-UTF8 path"); val.chars().filter(|c| c.is_alphanumeric()).collect::() }).collect(), struct_name: { let val = file.file_name().unwrap(); let val = val.to_os_string().into_string().unwrap(); let val = val.chars().filter_map(|c| if c.is_alphanumeric() || c == '_' { Some(c) } else if c == '.' { Some('_') } else { None }).collect::(); val.to_ascii_uppercase() }, struct_name_no_ext: { let val = file.file_stem().unwrap(); let val = val.to_os_string().into_string().unwrap(); let val = val.chars().filter_map(|c| if c.is_alphanumeric() || c == '_' { Some(c) } else if c == '.' { Some('_') } else { None }).collect::(); val.to_ascii_uppercase() }, resource_str_name: file.display().to_string(), resource_str_name_no_ext: if file.iter().count() == 1 { file.file_stem().unwrap().to_os_string().into_string().unwrap() } else { file.parent().unwrap().display().to_string() + "/" + &file.file_stem().unwrap().to_os_string().into_string().unwrap() }, file_path: base_dir.join(file).display().to_string(), enum_name: path_to_enum_variant(file), } }).collect::>(); let file_path = env::var("OUT_DIR").unwrap(); let file_path = Path::new(&file_path).join("pocket-resources.rs"); let mut file = File::create(&file_path).unwrap(); try!(writeln!(file, r#"#[derive(Debug, Clone, Hash, PartialEq, Eq)]"#)); try!(writeln!(file, r#"pub enum ResourceId {{"#)); for entry in &entries { try!(writeln!(file, r"{},", entry.enum_name)); } try!(writeln!(file, r#"}}"#)); try!(writeln!(file, r#"impl ResourceId {{"#)); try!(writeln!(file, r#" #[inline]"#)); try!(writeln!(file, r#" pub fn load(&self) -> &'static [u8] {{"#)); try!(writeln!(file, r#" match self {{"#)); for entry in &entries { try!(writeln!(file, r##" &ResourceId::{} => &include_bytes!(r#"{}/{}"#)[..], "##, entry.enum_name, env::var("CARGO_MANIFEST_DIR").unwrap(), entry.file_path)); } try!(writeln!(file, r#" }}"#)); try!(writeln!(file, r#" }}"#)); try!(writeln!(file, r#" #[inline]"#)); try!(writeln!(file, r#" pub fn name_ext(&self) -> &str {{"#)); try!(writeln!(file, r#" match *self {{"#)); for entry in &entries { try!(writeln!(file, r##" ResourceId::{} => r#"{}"#, "##, entry.enum_name, entry.resource_str_name)); } try!(writeln!(file, r#" }}"#)); try!(writeln!(file, r#" }}"#)); try!(writeln!(file, r#" #[inline]"#)); try!(writeln!(file, r#" pub fn from_name(name: &str) -> Option {{"#)); for entry in &entries { try!(writeln!(file, r##" if name == r#"{}"# {{ return Some(ResourceId::{}); }} "##, entry.resource_str_name, entry.enum_name)); if entry.resource_str_name != entry.resource_str_name_no_ext { if entries.iter().filter(|e| e.resource_str_name_no_ext == entry.resource_str_name_no_ext || e.resource_str_name == entry.resource_str_name_no_ext).count() == 1 { try!(writeln!(file, r##" if name == r#"{}"# {{ return Some(ResourceId::{}); }} "##, entry.resource_str_name_no_ext, entry.enum_name)); } } } try!(writeln!(file, r#" None"#)); try!(writeln!(file, r#" }}"#)); try!(writeln!(file, r#"}}"#)); try!(write(&entries, &[], &mut file)); Ok(()) } fn write(entries: &[Entry], base: &[String], output: &mut W) -> io::Result<()> where W: Write { let mut sub_paths = HashSet::new(); for entry in entries { if entry.path.len() > base.len() && &entry.path[..base.len()] == base { sub_paths.insert(&entry.path[base.len()]); } if entry.path != base { continue; } try!(write!(output, "#[allow(missing_docs)] pub const {}: ", entry.struct_name)); for _ in 0 .. base.len() { try!(write!(output, r"super::")); } try!(write!(output, "ResourceId = ")); for _ in 0 .. base.len() { try!(write!(output, r"super::")); } try!(writeln!(output, r"ResourceId::{};", entry.enum_name)); if entry.struct_name != entry.struct_name_no_ext { if entries.iter().filter(|e| e.struct_name_no_ext == entry.struct_name_no_ext || e.struct_name == entry.struct_name_no_ext).count() == 1 { try!(write!(output, "#[allow(missing_docs)] pub const {}: ", entry.struct_name_no_ext)); for _ in 0 .. base.len() { try!(write!(output, r"super::")); } try!(write!(output, "ResourceId = ")); for _ in 0 .. base.len() { try!(write!(output, r"super::")); } try!(writeln!(output, r"ResourceId::{};", entry.enum_name)); } } } for sub_path in sub_paths.iter() { try!(writeln!(output, r#" #[allow(missing_docs)] pub mod {} {{ "#, sub_path)); let mut base = base.to_vec(); base.push(sub_path.to_string()); try!(write(entries, &base, output)); try!(writeln!(output, r#" }} "#)); } Ok(()) } /// Turns a path into a variant name for the enumeration of resources. fn path_to_enum_variant

(path: P) -> String where P: AsRef { let path = path.as_ref(); let components = path.iter() .map(|val| { let val = val.to_str().expect("Cannot process non-UTF8 path"); let val = val.chars().filter(|c| c.is_alphanumeric()).collect::(); format!("{}{}", val[..1].to_ascii_uppercase(), val[1..].to_ascii_lowercase()) }).collect::>(); components.concat() }