use std::env;
use std::fs;
use std::fmt::{Debug, Display};
use std::io;
use std::io::Write;
use std::path::Path;
use std::str;
pub struct ConstWriter {
f: fs::File,
}
pub struct ConstValueWriter {
f: fs::File,
}
impl ConstWriter {
pub fn for_build(mod_name: &str) -> io::Result<ConstWriter> {
let out_dir = env::var("OUT_DIR").unwrap();
let mod_name = format!("{}.rs", mod_name);
let dest_path = Path::new(&out_dir).join(mod_name);
Ok(ConstWriter {
f: fs::File::create(&dest_path)?
})
}
pub fn from_path(path: &Path) -> io::Result<ConstWriter> {
let f = fs::OpenOptions::new()
.write(true)
.truncate(true)
.open(path)?;
Ok(ConstWriter {
f: f,
})
}
pub fn finish_dependencies(self) -> ConstValueWriter {
ConstValueWriter { f: self.f }
}
pub fn add_dependency(&mut self, lib: &str) {
write!(self.f, "pub use {};\n", lib).unwrap();
}
pub fn add_raw(&mut self, raw: &str) {
write!(self.f, "{}\n", raw).unwrap();
}
}
impl ConstValueWriter {
pub fn add_value<T: Debug>(&mut self, name: &str, ty: &str, value: T) {
self.add_value_raw(name, ty, &format!("{:?}", value));
}
pub fn add_value_raw(&mut self, name: &str, ty: &str, raw_value: &str) {
write!(
self.f, "pub const {}: {} = {};\n",
name,
ty,
raw_value,
).unwrap();
}
pub fn add_array<T: Debug>(&mut self, name: &str, ty: &str, values: &[T]) {
write_array(&mut self.f, name, ty, values);
}
pub fn add_array_raw<S: AsRef<str> + Display>(&mut self, name: &str, ty: &str, raw_values: &[S]) {
write_array_raw(&mut self.f, name, ty, raw_values);
}
pub fn add_raw(&mut self, raw: &str) {
write!(self.f, "{}\n", raw).unwrap();
}
pub fn finish(&mut self) {
self.f.flush().unwrap();
}
}
pub fn write_array<T: Debug, W: Write>(w: &mut W, name: &str, ty: &str, values: &[T])
-> String
{
assert!(
!values.is_empty(),
"attempting to add an array of len zero. If this is intentional, use \
add_value_raw instead."
);
let full_ty = write_array_header(w, name, ty, values.len());
for v in values.iter() {
write_array_item_raw(w, &format!("{:?}", v));
}
write_array_end(w);
full_ty
}
pub fn write_array_raw<W: Write, S: AsRef<str> + Display>(
w: &mut W, name: &str, ty: &str, raw_values: &[S]
)
-> String
{
assert!(
!raw_values.is_empty(),
"attempting to add an array of len zero. If this is intentional, use \
add_value_raw instead."
);
let full_ty = write_array_header(w, name, ty, raw_values.len());
for v in raw_values {
write_array_item_raw(w, v);
}
write_array_end(w);
full_ty
}
fn write_array_header<W: Write>(w: &mut W, name: &str, ty: &str, len: usize) -> String {
let full_ty = format!("[{}; {}]", ty, len);
write!(w, "pub const {}: {} = [\n", name, &full_ty).unwrap();
full_ty
}
fn write_array_item_raw<W: Write, S: AsRef<str> + Display>(w: &mut W, raw_item: S) {
write!(w, " {},\n", raw_item).unwrap()
}
fn write_array_end<W: Write>(w: &mut W) {
write!(w, "];\n").unwrap();
}