mac-0.1.1/.gitignore01006440000765000002400000000207124732543570012473 0ustar0000000000000000.DS_Store *~ *# *.o *.so *.swp *.dylib *.dSYM *.dll *.rlib *.dummy *.exe *-test /doc/ /target/ /examples/* !/examples/*.rs Cargo.lock mac-0.1.1/.travis.yml01006440000765000002400000001075124732543570012620 0ustar0000000000000000language: rust sudo: false script: - cargo build - cargo test - cargo bench --no-run - cargo doc after_success: - if [ "$TRAVIS_PULL_REQUEST" == false && test == "TRAVIS_BRANCH" == "master" ]; then - curl https://raw.githubusercontent.com/reem/rust-gh-docs/master/make-docs.sh > docs.sh - chmod u+x docs.sh - ./docs.sh reem project-name env: global: secure: QPYL1XUr4CyK/2DXlsYC1eCpWRpyEiqQSd/FFVR+YdP/rOJ7AyAXQqPhfgjDBQwvc6E2fUiyYjoV/xe1a757DDeZKlgd8Lp20fSDwvNt/Ejx8ueh3h3kuOtgDpIGSKX/l+XC+ltDpzjhh7bowI2/fOEf+kE53jvu9i4PiLnKdlY= mac-0.1.1/Cargo.toml01006440000765000002400000001415130514421230012414 0ustar0000000000000000# 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 = "mac" version = "0.1.1" authors = ["Jonathan Reem "] description = "A collection of great and ubiqutitous macros." readme = "README.md" license = "MIT/Apache-2.0" repository = "https://github.com/reem/rust-mac.git" mac-0.1.1/Cargo.toml.orig01006440000765000002400000000403130514421230013347 0ustar0000000000000000[package] name = "mac" version = "0.1.1" authors = ["Jonathan Reem "] repository = "https://github.com/reem/rust-mac.git" description = "A collection of great and ubiqutitous macros." readme = "README.md" license = "MIT/Apache-2.0" mac-0.1.1/README.md01006440000765000002400000000744124737370460011771 0ustar0000000000000000# mac > A collection of great and ubiqutitous macros. ## Overview This crate contains collections of macros which are useful in many situations, and usable independently or together. ## Usage Use the crates.io repository; add this to your `Cargo.toml` along with the rest of your dependencies: ```toml [dependencies] mac = "*" ``` ## Author [Jonathan Reem](https://medium.com/@jreem) is the primary author and maintainer of mac. ## License MIT/Apache-2.0, like rust itself mac-0.1.1/src/cfg.rs01006440000765000002400000003472125064352670012404 0ustar0000000000000000//! Macros for conditional compilation. /// Compile-time matching on config variables. /// /// Only the branch relevant on your machine will be type-checked! /// /// # Example /// /// ``` /// # #[macro_use] extern crate mac; /// # fn main() { /// let mascot = match_cfg! { /// (target_os = "linux") => "penguin", /// (target_os = "openbsd") => "blowfish", /// _ => "unknown", /// }; /// println!("{}", mascot); /// # } /// ``` /// #[macro_export] macro_rules! match_cfg { ( $( ($cfg:meta) => $e:expr, )* _ => $last:expr, ) => { match () { $( #[cfg($cfg)] () => $e, )* #[cfg(all( $( not($cfg) ),* ))] () => $last, } }; ( $( ($cfg:meta) => $e:expr, )* ) => { match_cfg! { $( ($cfg) => $e, )* _ => { #[allow(dead_code)] #[static_assert] static MATCH_CFG_FALLBACK_UNREACHABLE: bool = false; } } }; } /// Compile-time conditional expression. /// /// # Example /// /// ``` /// # #[macro_use] extern crate mac; /// # fn main() { /// if_cfg!(test { /// println!("Crate built as a test suite"); /// }) /// # } /// ``` /// /// Unlike `if cfg!(...)`, this will not even compile the unused branch. /// /// ``` /// # #[macro_use] extern crate mac; /// # fn main() { /// let x = if_cfg!(any(bleh, blah="bluh") { /// some_undefined_function_name(); /// 2 + "doesn't even typecheck" /// } else { /// 3 /// }); /// /// assert_eq!(x, 3); /// # } /// ``` #[macro_export] macro_rules! if_cfg { ($cfg:meta $t:block else $f:block) => { match_cfg! { ($cfg) => $t, _ => $f, } }; ($cfg:meta $t:block) => { if_cfg!($cfg $t else { }) }; } mac-0.1.1/src/format.rs01006440000765000002400000002705130514421150013115 0ustar0000000000000000//! Macros for string formatting. /// Conditionally perform string formatting. /// /// If `$enabled` is true, then do the formatting and return a `Cow::Owned`. /// /// Otherwise, just return the borrowed (often `'static`) string /// `$borrowed`. /// /// When `$enabled` is false, this avoids the overhead of allocating /// and writing to a buffer, as well as any overhead or side effects /// of the format arguments. /// /// # Example /// /// You can use `format_if` to implement a detailed error logging facility /// that can be enabled at runtime. /// /// ``` /// # #[macro_use] extern crate mac; /// # use std::borrow::Cow::{Borrowed, Owned}; /// # fn main() { /// let formatted = format_if!(true, "Vague error", "Error code {:?}", 3); /// /// assert_eq!(&formatted[..], "Error code 3"); /// if let Borrowed(_) = formatted { /// panic!("Wrong!") /// } /// /// let not_formatted = format_if!(false, "Vague error", "Error code {:?}", { /// // Note that the argument is not evaluated. /// panic!("oops"); /// }); /// /// assert_eq!(¬_formatted[..], "Vague error"); /// if let Owned(_) = not_formatted { /// panic!("Wrong!") /// } /// # } /// ``` #[macro_export] macro_rules! format_if { ($enabled:expr, $borrowed:expr, $fmt:expr, $($args:expr),*) => { if $enabled { ::std::borrow::Cow::Owned(format!($fmt, $($args),*)) as ::std::borrow::Cow } else { ::std::borrow::Cow::Borrowed($borrowed) } } } mac-0.1.1/src/inspect.rs01006440000765000002400000005114125064352670013305 0ustar0000000000000000//! Inspect Macros /// Evaluates an expression, prints a stringified version of the expression /// along with the evaluated value, and then returns that value. /// /// # Example /// /// ``` /// # #[macro_use] extern crate mac; /// /// # fn main() { /// fn lcm_2_to_4() -> u32 { /// let mut i = 1; /// loop { /// if inspect!(i % 2, i % 3, i % 4) == (0, 0, 0) { /// return inspect!("done: i = " => i); /// } /// i += 1; /// } /// } /// assert_eq!(lcm_2_to_4(), 12); /// # } /// ``` /// /// Returns `12`, and prints the following to stdout: /// /// ```ignore /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 1, 1) /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 2, 2) /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 0, 3) /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 1, 0) /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 2, 1) /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 0, 2) /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 1, 3) /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 2, 0) /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 0, 1) /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 1, 2) /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 2, 3) /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 0, 0) /// src/inspect.rs:95 - done: i = 12 /// ``` #[macro_export] macro_rules! inspect { ($prefix:expr => $expr:expr) => {{ let val = $expr; println!("{}:{} - {}{:?}", file!(), line!(), $prefix, val); val }}; ($expr:expr) => { inspect!(concat!(stringify!($expr), " = ") => $expr) }; ($prefix:expr => $($expr:expr),+) => { inspect!($prefix => ($($expr),+)) }; ($($expr:expr),+) => { inspect!(($($expr),+)) }; } #[test] fn test_inspect() { assert_eq!(inspect!("foo"), "foo"); assert_eq!(inspect!("" => "foo"), "foo"); assert_eq!(inspect!(1 + 2, 2 + 3, 3 + 4), (3, 5, 7)); assert_eq!(inspect!("" => 1 + 2, 2 + 3, 3 + 4), (3, 5, 7)); fn fib(n: u64) -> u64 { inspect!("fib :: n = " => n); inspect! { "ret = " => match n { 0 | 1 => n, n => fib(n-1) + fib(n-2) }} } fn fib_iter(n: u64) -> u64 { inspect!("fib_iter :: n = " => n); let (mut a, mut b) = (0, 1); for _ in 0..n { inspect!(a, b); let tmp = b; b += a; a = tmp; } inspect!("ret = " => a) } assert_eq!(fib(4), 3); assert_eq!(fib_iter(7), 13); // Uncomment the following to see the output in `cargo test`. // panic!() } mac-0.1.1/src/lib.rs01006440000765000002400000002666125064352670012417 0ustar0000000000000000#![cfg_attr(test, deny(warnings))] #![deny(missing_docs)] //! # mac //! //! A collection of great and ubiqutitous macros. //! pub mod test; pub mod mem; pub mod format; pub mod syntax_ext; pub mod matches; pub mod inspect; pub mod cfg; /// Unwraps an `Option` or returns from the function with the specified return /// value. /// /// Can be used on `Result`s by first calling `.ok()` or `.err()` on them. /// /// # Examples /// /// ``` /// # #[macro_use] extern crate mac; /// fn take_pair(iter: &mut I) -> Option<(::Item, ::Item)> { /// let first = unwrap_or_return!(iter.next(), None); /// Some((first, unwrap_or_return!(iter.next(), None))) /// } /// # fn main() { } /// ``` #[macro_export] macro_rules! unwrap_or_return { ($e:expr, $r:expr) => (match $e { Some(e) => e, None => return $r, }) } /// Do-while loop. /// /// # Examples /// /// ``` /// # #[macro_use] extern crate mac; /// # fn main() { /// let mut i = 0; /// let mut n = 0; /// /// do_while!({ /// n += i; /// i += 1; /// } while i < 5); /// /// assert_eq!(n, 10); /// # } /// ``` /// /// The loop always executes at least once. /// /// ``` /// # #[macro_use] extern crate mac; /// # fn main() { /// let mut ran = false; /// do_while!({ ran = true } while false); /// assert!(ran); /// # } /// ``` #[macro_export] macro_rules! do_while { ($body:block while $condition:expr) => { while { $body; $condition } { } } } mac-0.1.1/src/matches.rs01006440000765000002400000001764124761557020013272 0ustar0000000000000000//! Pattern Matching macros. /// Returns true if an expression matches a pattern. /// /// # Example /// /// ``` /// # #[macro_use] extern crate mac; /// /// # fn main() { /// assert!(matches!(2, 1 | 2 | 3)); /// assert!(matches!('x', 'a' ... 'z')); /// assert!(!matches!(Some(1), None)); /// assert!(matches!(Some(42), Some(n) if n == 42)); /// # } /// ``` #[macro_export] macro_rules! matches { ($expr:expr, $($pat:tt)+) => { _tt_as_expr_hack! { match $expr { $($pat)+ => true, _ => false } } } } /// Work around "error: unexpected token: `an interpolated tt`", whatever that /// means. (Probably rust-lang/rust#22819.) #[doc(hidden)] #[macro_export] macro_rules! _tt_as_expr_hack { ($value:expr) => ($value) } #[test] fn test_matches() { let foo = Some("-12"); assert!(matches!(foo, Some(bar) if matches!(bar.as_bytes()[0], b'+' | b'-') && matches!(bar.as_bytes()[1], b'0'... b'9') )); } mac-0.1.1/src/mem.rs01006440000765000002400000002077124761557020012422 0ustar0000000000000000//! Macros for low-level memory manipulation. /// Make a tuple of the addresses of some of a struct's fields. /// /// This is useful when you are transmuting between struct types /// and would like an additional dynamic check that the layouts /// match. It's difficult to make such an assertion statically /// in Rust at present. /// /// # Example /// /// ``` /// # #[macro_use] extern crate mac; /// use std::mem; /// /// # fn main() { /// struct Foo { x: i32, y: i32 } /// struct Bar { x: u32, y: u32 } /// /// let foo = Foo { x: 3, y: 4 }; /// let old_addrs = addrs_of!(foo => x, y); /// /// let bar = unsafe { /// mem::transmute::<&Foo, &Bar>(&foo) /// }; /// let new_addrs = addrs_of!(bar => x, y); /// assert_eq!(old_addrs, new_addrs); /// /// assert_eq!(bar.x, 3); /// assert_eq!(bar.y, 4); /// # } /// ``` #[macro_export] macro_rules! addrs_of { ($obj:expr => $($field:ident),+) => { ( // make a tuple $( unsafe { ::std::mem::transmute::<_, usize>(&$obj.$field) } ),+ ) } } mac-0.1.1/src/syntax_ext.rs01006440000765000002400000001470124761557020014046 0ustar0000000000000000//! Macros useful when writing procedural syntax extensions. //! //! The macros themselves are ordinary `macro_rules!` macros. /// Call `span_err` on an `ExtCtxt` and return `DummyResult::any`. #[macro_export] macro_rules! ext_bail { ($cx:expr, $sp:expr, $msg:expr) => {{ $cx.span_err($sp, $msg); return ::syntax::ext::base::DummyResult::any($sp); }} } /// `ext_bail!` if the condition `$e` is true. #[macro_export] macro_rules! ext_bail_if { ($e:expr, $cx:expr, $sp:expr, $msg:expr) => {{ if $e { ext_bail!($cx, $sp, $msg) } }} } /// Unwrap the `Option` `$e`, or `ext_bail!`. #[macro_export] macro_rules! ext_expect { ($cx:expr, $sp:expr, $e:expr, $msg:expr) => {{ match $e { Some(x) => x, None => ext_bail!($cx, $sp, $msg), } }} } mac-0.1.1/src/test.rs01006440000765000002400000001007124761557020012613 0ustar0000000000000000//! Macros for writing test suites. /// Generate a test function `$name` which asserts that `$left` and `$right` /// are equal. /// /// # Example /// /// ``` /// # #[macro_use] extern crate mac; /// mod test { /// # // doesn't actually run the test :/ /// test_eq!(two_and_two_is_four, 2 + 2, 4); /// } /// # fn main() { } /// ``` #[macro_export] macro_rules! test_eq { ($name:ident, $left:expr, $right:expr) => { #[test] fn $name() { assert_eq!($left, $right); } } }