build_const-0.2.1/.gitignore010064400017500000144000000000361326414043200142220ustar0000000000000000target/ **/*.rs.bk Cargo.lock build_const-0.2.1/Cargo.toml.orig010064400017500000144000000006151326414111200151200ustar0000000000000000[package] name = "build_const" authors = ["Garrett Berg "] description = "library for creating importable constants from build.rs or a script" keywords = ["embedded", "no_std", "build", "const", "static"] license = "MIT" repository = "https://github.com/vitiral/build_const" documentation = "https://docs.rs/build_const" version = "0.2.1" [features] default = ["std"] std = [] build_const-0.2.1/Cargo.toml0000644000000016310000000000000113770ustar00# 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 = "build_const" version = "0.2.1" authors = ["Garrett Berg "] description = "library for creating importable constants from build.rs or a script" documentation = "https://docs.rs/build_const" keywords = ["embedded", "no_std", "build", "const", "static"] license = "MIT" repository = "https://github.com/vitiral/build_const" [features] default = ["std"] std = [] build_const-0.2.1/LICENSE.txt010064400017500000144000000021121326414043200140520ustar0000000000000000The MIT License (MIT) Copyright (c) 2017 Garrett Berg, vitiral@gmail.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. build_const-0.2.1/README.md010064400017500000144000000004141326414043200135110ustar0000000000000000# `build_const`: crate for creating constants in your build script Rust library for creating importable constants from build.rs or a script See the [crate documentation](https://docs.rs/build_const) and the crate on [crates.io](https://crates.io/crates/build_const) build_const-0.2.1/justfile010064400017500000144000000002151326414043200140010ustar0000000000000000 test: cd test_crates/example && rm -f Cargo.lock && cargo test && cd .. cd test_crates/no_std && rm -f Cargo.lock && cargo test && cd .. build_const-0.2.1/src/lib.rs010064400017500000144000000047271326414105400141510ustar0000000000000000//! `build_const`: crate for creating constants in your build script //! //! The build_const crate exists to help create rust constant files at compile time or in a //! generating script. It is ultra simple and lightweight, making constant creation a simple //! matter. //! //! Recommended use: when developing make your constants in `build.rs`. Once your constants are //! fairly stable create a script instead and have your constants file be generated in either a //! single file or an external crate that you can bring in as a dependency. //! //! # Example //! //! Include `build_const = VERSION` in your `Cargo.toml` file. For `no_std` support (macros only) //! use `default-features = false`. //! //! See `ConstWriter` for how to use in a build.rs or script. To then import a "constants.rs" file //! created in `build.rs` use: //! //! ```c //! #[macro_use] //! extern crate build_const; //! //! build_const!("constants"); //! println!("VALUE: {}", VALUE); //! println!("VALUE: {}", ARRAY); //! ``` //! //! For writing constants in a script, the macro `src_file!` is also provided. //! ```c //! // will write files to `/src/constants.rs` //! let mut consts = ConstWriter::from_path(&Path::from(src_file!("constants.rs"))).unwrap(); //! // ... use consts //! ``` #![cfg_attr(not(feature = "std"), no_std)] #[cfg(feature = "std")] mod writer; #[cfg(feature = "std")] pub use writer::{ ConstWriter, ConstValueWriter, write_array, write_array_raw, }; /// Shortcut macro which expands to the same module path used in /// `ConstWriter::for_build(mod_name)`. /// /// If you don't want to include macros, this is simply a one liner: /// ```ignore /// include!(concat!(env!("OUT_DIR"), concat!("/", $mod_name))); /// ``` #[macro_export] macro_rules! build_const { ( $mod_name:expr ) => { include!( concat!( env!("OUT_DIR"), concat!("/", concat!($mod_name, ".rs")) ) ); }; } /// Macro which returns the path to file in your `src/` directory. /// /// Example: /// ```ignore /// src_file!("constants.rs"); /// ``` /// returns `/path/to/project/src/constants.rs` /// /// If you need a more custom path, the basic implementation is: /// ```ignore /// concat!(env!("CARGO_MANIFEST_DIR"), "/src/path/to/file") /// ``` #[macro_export] macro_rules! src_file { ( $file_name:expr) => { concat!( env!("CARGO_MANIFEST_DIR"), concat!("/", concat!("src", concat!("/", $file_name))) ) }; } build_const-0.2.1/src/writer.rs010064400017500000144000000154321326414043200147110ustar0000000000000000use std::env; use std::fs; use std::fmt::Debug; use std::io; use std::io::Write; use std::path::Path; use std::str; /// Primary object used to write constant files. /// /// # Example /// ```no_run /// # use std::path::Path; /// # #[derive(Debug)] /// # struct Point { x: u8, y: u8 } /// use build_const::ConstWriter; /// /// // use `for_build` in `build.rs` /// let mut consts = ConstWriter::from_path( /// &Path::new("/tmp/constants.rs") /// ).unwrap(); /// /// // add an external dependency (`use xyz::Point`) /// consts.add_dependency("xyz::Point"); /// /// // finish dependencies and starting writing constants /// let mut consts = consts.finish_dependencies(); /// /// // add an array of values /// let values: Vec = vec![1, 2, 3, 36]; /// consts.add_array("ARRAY", "u8", &values); /// /// // Add a value that is a result of "complex" calculations /// consts.add_value("VALUE", "u8", values.iter().sum::()); /// /// // Add a value from an external crate (must implement `Debug`) /// consts.add_value("VALUE", "Point", &Point { x: 3, y: 7}); /// ``` pub struct ConstWriter { f: fs::File, } /// Created from `ConstWriter::finish_dependencies`. See /// documentation for `ConstWriter`. pub struct ConstValueWriter { f: fs::File, } impl ConstWriter { /// Create a ConstWriter to be used for your crate's `build.rs` pub fn for_build(mod_name: &str) -> io::Result { 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)? }) } /// Create a new ConstWriter to write to an path. If a file /// already exists at the path then it will be deleted. pub fn from_path(path: &Path) -> io::Result { let f = fs::OpenOptions::new() .write(true) .truncate(true) .open(path)?; Ok(ConstWriter { f: f, }) } /// finish writing dependencies and start writing constants pub fn finish_dependencies(self) -> ConstValueWriter { ConstValueWriter { f: self.f } } /// Add a dependency to your constants file. pub fn add_dependency(&mut self, lib: &str) { write!(self.f, "pub use {};\n", lib).unwrap(); } /// Add a raw string to the constants file. /// /// This method only changes `raw` by adding a `\n` at the end. pub fn add_raw(&mut self, raw: &str) { write!(self.f, "{}\n", raw).unwrap(); } } impl ConstValueWriter { /// Add a value to the constants file. /// /// You have to manually specify the `name`, type (`ty`) and `value` /// of the constant you want to add. /// /// The `value` uses the `Debug` trait to determine the formating of /// the value being added. If `Debug` is not accurate or will not work, /// you must use `add_value_raw` instead and format it yourself. pub fn add_value(&mut self, name: &str, ty: &str, value: T) { self.add_value_raw(name, ty, &format!("{:?}", value)); } /// Add a pre-formatted value to the constants file. /// /// `add_value` depends on `Debug` being implemented in such a way /// that it accurately represents the type's creation. Sometimes that /// cannot be relied on and `add_value_raw` has to be used instead. 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(); } /// Add an array of len > 0 to the constants /// /// You have to manually specify the `name`, type (`ty`) of the **items** and /// `values` of the array constant you want to add. The length of the array /// is determined automatically. /// /// Example: `const.add_array("foo", "u16", &[1,2,3])` /// /// The `value` of each item uses the `Debug` trait to determine the /// formatting of the value being added. If `Debug` is not accurate or will /// not work, you must use `add_array_raw` instead and format it yourself. pub fn add_array(&mut self, name: &str, ty: &str, values: &[T]) { write_array(&mut self.f, name, ty, values); } /// Add an array of pre-formatted values to the constants file. The length of the array is /// determined automatically. /// /// `add_array` depends on `Debug` being implemented for each item in such a way that it /// accurately represents the item's creation. Sometimes that cannot be relied on and /// `add_array_raw` has to be used instead. pub fn add_array_raw(&mut self, name: &str, ty: &str, raw_values: &[&str]) { write_array_raw(&mut self.f, name, ty, raw_values); } /// Add a raw string to the constants file. /// /// This method only changes `raw` by adding a `\n` at the end. pub fn add_raw(&mut self, raw: &str) { write!(self.f, "{}\n", raw).unwrap(); } /// Finish writing to the constants file and consume self. pub fn finish(&mut self) { self.f.flush().unwrap(); } } // Public Functions /// Write an array and return the array's full type representation. /// /// This can be used to create nested array constant types. pub fn write_array(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 } /// Write an array of raw values and return the array's full type representation. /// /// This can be used to create nested array constant types. pub fn write_array_raw( w: &mut W, name: &str, ty: &str, raw_values: &[&str] ) -> 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 } // Helpers /// Write the array header and return the array's full type. fn write_array_header(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: &mut W, raw_item: &str) { write!(w, " {},\n", raw_item).unwrap() } fn write_array_end(w: &mut W) { write!(w, "];\n").unwrap(); }