2016-05-23 21:50:13 +03:00
|
|
|
extern crate brotli2;
|
|
|
|
extern crate flate2;
|
2016-04-22 23:42:10 +03:00
|
|
|
extern crate md5;
|
|
|
|
extern crate rustc_serialize as serialize;
|
2016-05-23 21:50:13 +03:00
|
|
|
extern crate sass_rs;
|
|
|
|
extern crate sass_sys;
|
2016-04-22 23:42:10 +03:00
|
|
|
|
2016-05-23 21:50:13 +03:00
|
|
|
use brotli2::write::BrotliEncoder;
|
|
|
|
use flate2::{Compression, FlateWriteExt};
|
2016-04-22 23:42:10 +03:00
|
|
|
use sass_rs::dispatcher::Dispatcher;
|
|
|
|
use sass_rs::sass_context::SassFileContext;
|
|
|
|
use serialize::base64::{self, ToBase64};
|
|
|
|
use std::env;
|
|
|
|
use std::fs::{File, create_dir_all};
|
|
|
|
use std::io::Write;
|
2016-05-21 18:56:48 +03:00
|
|
|
use std::path::PathBuf;
|
2016-04-22 23:42:10 +03:00
|
|
|
use std::thread;
|
|
|
|
|
|
|
|
fn main() {
|
2016-05-21 18:56:48 +03:00
|
|
|
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
|
|
|
|
let static_dir = out_dir.join("static").join("static");
|
|
|
|
create_dir_all(&static_dir).unwrap();
|
|
|
|
|
2016-04-22 23:42:10 +03:00
|
|
|
let css = compile("photos.scss").unwrap();
|
2016-05-21 18:56:48 +03:00
|
|
|
let filename = format!("style-{}.css", checksum_slug(&css));
|
|
|
|
|
|
|
|
File::create(&static_dir.join(&filename))
|
|
|
|
.map(|mut f| {
|
|
|
|
write!(f, "{}", css).unwrap();
|
|
|
|
})
|
|
|
|
.unwrap();
|
2016-05-23 21:50:13 +03:00
|
|
|
File::create(&static_dir.join(format!("{}.gz", &filename)))
|
|
|
|
.map(|f| {
|
|
|
|
write!(f.gz_encode(Compression::Best), "{}", css).unwrap();
|
|
|
|
})
|
|
|
|
.unwrap();
|
|
|
|
File::create(&static_dir.join(format!("{}.br", &filename)))
|
|
|
|
.map(|f| {
|
|
|
|
write!(BrotliEncoder::new(f, 11), "{}", css).unwrap();
|
|
|
|
})
|
|
|
|
.unwrap();
|
2016-05-21 18:56:48 +03:00
|
|
|
|
|
|
|
File::create(&out_dir.join("stylelink"))
|
|
|
|
.map(|mut f| {
|
|
|
|
writeln!(f,
|
|
|
|
"\"<link rel='stylesheet' href='/static/{}' \
|
|
|
|
type='text/css'/>\"",
|
|
|
|
filename)
|
|
|
|
.unwrap();
|
|
|
|
})
|
|
|
|
.unwrap();
|
2016-05-03 19:46:44 +03:00
|
|
|
|
|
|
|
println!("cargo:rerun-if-changed=src/sassify.rs");
|
|
|
|
// TODO Find any referenced files!
|
|
|
|
println!("cargo:rerun-if-changed=photos.scss");
|
2016-04-22 23:42:10 +03:00
|
|
|
}
|
|
|
|
|
2016-05-21 18:56:48 +03:00
|
|
|
/// A short and url-safe checksum string from string data.
|
|
|
|
fn checksum_slug(data: &str) -> String {
|
|
|
|
md5::compute(data.as_bytes())[9..].to_base64(base64::URL_SAFE)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Setup the sass environment and compile a file.
|
|
|
|
fn compile(filename: &str) -> Result<String, String> {
|
2016-04-22 23:42:10 +03:00
|
|
|
let mut file_context = SassFileContext::new(filename);
|
2016-04-23 23:15:21 +03:00
|
|
|
// options.set_output_style(COMPRESSED) or similar, when supported.
|
2016-05-21 18:56:48 +03:00
|
|
|
if let Ok(mut opt) = file_context.sass_context.sass_options.write() {
|
2016-04-23 23:15:21 +03:00
|
|
|
unsafe {
|
|
|
|
sass_sys::sass_option_set_output_style(
|
|
|
|
opt.raw.get_mut(),
|
|
|
|
sass_sys::SASS_STYLE_COMPRESSED);
|
|
|
|
}
|
|
|
|
}
|
2016-05-21 18:56:48 +03:00
|
|
|
let options = file_context.sass_context.sass_options.clone();
|
|
|
|
thread::spawn(move || {
|
|
|
|
let dispatcher = Dispatcher::build(vec![], options);
|
2016-04-22 23:42:10 +03:00
|
|
|
while dispatcher.dispatch().is_ok() {}
|
|
|
|
});
|
|
|
|
file_context.compile()
|
|
|
|
}
|