[−][src]Crate overrider
overrider
is a crate for making dynamic compilation easier.
About
overrider
aims to bring the override
keyword of some other programming languages,
such as Java and Python, to Rust. With this crate, a base implimentation of a function,
method, or other item can be defined and then later overriden. All of this happens at
compilation time.
overrider
also allows for defining flags
. By parsing flags with clap
in a
lazy_static
, highly efficient switching of functionality due to input flags
can be achieved.
Quick Example
The following code shows how overrider
is used in src
file:
use overrider::*; #[default] fn main() { println!("This is the base implimentation"); } #[override_default] fn main() { println!("This is the overriden implimentation"); }
Easy as that. If the second implimentation is included, the output changes.
How about with flags?
use overrider::*; use clap::{Arg, ArgMatches, App}; use lazy_static::lazy_static; lazy_static! { static ref CLAP_FLAGS: ArgMatches<'static> = { App::new("Overrider example - flag") .arg(Arg::with_name("change").long("change")) .get_matches() }; } #[default] fn main() { println!("Nothing to see here"); } #[override_flag(flag = change)] fn main() { println!("I'll be printed if you call this program with --change"); }
Why not traits?
Rust has a powerful trait system which allows somewhat similar functionality.
However, it does not allow multiple, concurrent definitions without conflict.
Additionally, traits do not have built in support for flags.
Impl
Due to limitations of proc_macro
, all overrider
flags must be attached to
the ouside of an impl
block, not the inside.
The following is correct:
#[default] impl Foo { fn bar(){} }
The following is not correct;
impl Foo { #[default] fn bar(){} }
Currently, overrider
allows for the following items inside an impl
block to
be manipulated:
fn
(methods)const
ants
Building
Because of limitations in proc_macro
, overrider
will not work without
it's sister crate overrider_build
. This is because overrider_build
parses
Rust files, supplying the rustc
configuration flags nessicary for conditional
compilation. For the above files, placing this code in build.rs
will do the trick:
fn main() { overrider_build::watch_files(vec!["src/main.rs"]); }
For more information, see the overrider_build
documentation.
More examples
Additional examples, verified to work, can be seen
online.
Try cloning the repository and running examples with cargo run -p EXAMPLE_NAME
Attribute Macros
default | Marks an item as the base implimentation |
override_default | Replaces (overrides) base implimentation |
override_final | Throw a compiler error to help ensure this item gets compiled |
override_flag | Override a base implimentation, but only when runtime is called with certain flags |