//! Realia provides attribute macros for conditional compilation,
//! analogous to `#[cfg(...)]` and `#[cfg_attr(...)]`.
extern crate proc_macro;
use crate Then;
use crate Expr;
use TokenStream;
use ;
use quote;
use ;
/// Checks whether an environment variable is defined and optionally
/// what value it has.
///
/// If you use this attribute, your project should include a `build.rs` that
/// triggers a rebuild when any environment variables of interest change:
///
/// ```
/// fn main() {
/// // Necessary when using #[realia::env("FOO")]
/// println!("cargo:rerun-if-env-changed=FOO");
/// }
/// ```
///
/// # Example
/// ```
/// #[realia::env("CI")]
/// fn example() {
/// println!("CI is defined");
/// }
/// ```
///
/// ```
/// #[realia::env("CI", "true")]
/// fn example() {
/// println!("CI is set to true");
/// }
/// ```
/// Checks whether an executable exists on the `PATH`.
///
/// If you use this attribute, your project should include a `build.rs` that
/// triggers a rebuild when the `PATH` environment variable changes:
///
/// ```
/// fn main() {
/// println!("cargo:rerun-if-env-changed=PATH");
/// }
/// ```
///
/// # Example
/// ```
/// #[realia::cmd("git")]
/// fn example() {
/// println!("Git is installed and available");
/// }
/// ```
/// Checks whether a crate has a certain dependency and optionally if that
/// dependency is a certain version.
///
/// The first argument is an "anchor crate", which should generally be your crate.
/// Since this functionality is implemented by checking the output of
/// `cargo metadata --manifest-path $CARGO_MANIFEST_DIR/Cargo.toml`,
/// the anchor is used to ensure consistent results when `$CARGO_MANIFEST_DIR`
/// changes (e.g., when building your crate directly vs when building a downstream crate).
///
/// This accounts for target-specific dependencies, but currently ignores any
/// optional dependencies enabled by features.
///
/// # Example
/// ```
/// #[realia::dep("realia", "syn")]
/// fn example() {
/// println!("Realia depends on Syn");
/// }
/// ```
///
/// ```
/// #[realia::dep("realia", "syn", "1.0.34")]
/// fn example() {
/// println!("Realia uses Syn 1.0.34 exactly");
/// }
/// ```
/// Checks whether a crate has a certain dependency at or above a certain version.
///
/// The first argument is an "anchor crate", which should generally be your crate.
/// Since this functionality is implemented by checking the output of
/// `cargo metadata --manifest-path $CARGO_MANIFEST_DIR/Cargo.toml`,
/// the anchor is used to ensure consistent results when `$CARGO_MANIFEST_DIR`
/// changes (e.g., when building your crate directly vs when building a downstream crate).
///
/// This accounts for target-specific dependencies, but currently ignores any
/// optional dependencies enabled by features.
///
/// # Example
/// ```
/// #[realia::dep_since("realia", "syn", "1.0.34")]
/// fn example() {
/// println!("Realia uses Syn 1.0.34 or newer");
/// }
/// ```
/// Checks whether a crate has a certain dependency below a certain version.
///
/// The first argument is an "anchor crate", which should generally be your crate.
/// Since this functionality is implemented by checking the output of
/// `cargo metadata --manifest-path $CARGO_MANIFEST_DIR/Cargo.toml`,
/// the anchor is used to ensure consistent results when `$CARGO_MANIFEST_DIR`
/// changes (e.g., when building your crate directly vs when building a downstream crate).
///
/// This accounts for target-specific dependencies, but currently ignores any
/// optional dependencies enabled by features.
///
/// # Example
/// ```
/// #[realia::dep_before("realia", "syn", "1.0.34")]
/// fn example() {
/// println!("Realia uses Syn 1.0.33 or older");
/// }
/// ```
/// Checks whether a crate has a certain dependency installed from the registry
/// (as opposed to being a Git dependency or a path dependency). This is useful
/// if you have non-registry dependencies with a
/// [registry fallback for publishing](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#multiple-locations).
///
/// The first argument is an "anchor crate", which should generally be your crate.
/// Since this functionality is implemented by checking the output of
/// `cargo metadata --manifest-path $CARGO_MANIFEST_DIR/Cargo.toml`,
/// the anchor is used to ensure consistent results when `$CARGO_MANIFEST_DIR`
/// changes (e.g., when building your crate directly vs when building a downstream crate).
///
/// This accounts for target-specific dependencies, but currently ignores any
/// optional dependencies enabled by features.
///
/// # Example
/// ```
/// #[realia::dep_from_registry("realia", "syn")]
/// fn example() {
/// println!("Realia uses Syn from the registry");
/// }
/// ```
/// Inverts another condition.
///
/// # Example
/// ```
/// #[realia::not(cmd("git"))]
/// fn example() {
/// println!("Git is not installed");
/// }
/// ```
/// Checks if at least one of multiple conditions is met.
///
/// # Example
/// ```
/// #[realia::any(cmd("git"), cmd("hg"))]
/// fn example() {
/// println!("Some version control is available");
/// }
/// ```
/// Checks if multiple conditions are met.
///
/// # Example
/// ```
/// #[realia::all(cmd("git"), env("GIT_AUTHOR_NAME"))]
/// fn example() {
/// println!("Git is available and GIT_AUTHOR_NAME is defined");
/// }
/// ```
/// Applies an attribute when the condition is met.
/// You can also specify `const` this way.
///
/// # Example
/// ```
/// #[test]
/// #[realia::attr(not(cmd("git")), ignore)]
/// fn some_test_that_requires_git() {}
/// ```
///
/// ```
/// #[realia::attr(env("USE_CONST_FN"), const)]
/// fn this_becomes_const() {}
/// ```