Skip to content

Commit

Permalink
Merge #17
Browse files Browse the repository at this point in the history
17: Derive various num traits for newtypes r=cuviper a=asayers

This PR adds deriving macros for the following traits:

* FromPrimitive
* ToPrimitive
* NumOps<Self, Self>
* NumCast
* Zero
* One
* Num
* Float

These macros only work when applied to a newtype where the inner type already
implements the trait in question.  They produce the obvious
"unwrap-call-rewrap" implementation.

The `FromPrimative` and `ToPrimative` macros now handle both newtypes and the
enums that they used to handle.

The odd one out is `NumOps`, for two reasons.  First, `NumOps` is just a trait
alias for `Add + Sub + Mul + Div + Rem`, so those are the traits which the
macro generates impls for.  I suppose it's not a great user experience to say
`#[derive(Foo)]` and end up with `impl Bar`, but I think in this case it's just
about OK.  After all, the user needs only to look at the definition of `NumOps`
to know that this is only possible behaviour - there's no other way to get an
impl for `NumOps`.

The other reason this one is strange is that when the user says
`#[derive(NumOps)]`, the macro decides that what they want is an impl for
`NumOps<Rhs=Self, Output=Self>`.  I think this makes sense though; these are
the default type parameters, so when you say `NumOps` unqualified this is what
it means.

As you can probably tell, my objective here was to get to `Float`.  That's why
this PR only provides macros for a subset of the traits in `num_traits`.  Our
codebase has a bunch of newtyped `f64`s, and I don't want people unwrapping
them all the time to work with them.

### To-do

- [x] docs
- [x] tests
- [x] RELEASES entry

Co-authored-by: Alex Sayers <[email protected]>
Co-authored-by: Josh Stone <[email protected]>
  • Loading branch information
3 people committed Oct 3, 2018
2 parents 599b9ef + 706ea88 commit be3163a
Show file tree
Hide file tree
Showing 5 changed files with 696 additions and 85 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ name = "num-derive"
repository = "https://github.com/rust-num/num-derive"
version = "0.2.2"
readme = "README.md"
build = "build.rs"

[dependencies]
num-traits = "0.2"
Expand Down
7 changes: 7 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# Unreleased

- [Added newtype deriving][17] for `FromPrimitive`, `ToPrimitive`,
`NumOps<Self, Self>`, `NumCast`, `Zero`, `One`, `Num`, and `Float`.

[17]: https://github.com/rust-num/num-derive/pull/17

# Release 0.2.2 (2018-05-22)

- [Updated dependencies][14].
Expand Down
35 changes: 35 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use std::env;
use std::io::Write;
use std::process::{Command, Stdio};

fn main() {
if probe("fn main() { 0i128; }") {
println!("cargo:rustc-cfg=has_i128");
} else if env::var_os("CARGO_FEATURE_I128").is_some() {
panic!("i128 support was not detected!");
}
}

/// Test if a code snippet can be compiled
fn probe(code: &str) -> bool {
let rustc = env::var_os("RUSTC").unwrap_or_else(|| "rustc".into());
let out_dir = env::var_os("OUT_DIR").expect("environment variable OUT_DIR");

let mut child = Command::new(rustc)
.arg("--out-dir")
.arg(out_dir)
.arg("--emit=obj")
.arg("-")
.stdin(Stdio::piped())
.spawn()
.expect("rustc probe");

child
.stdin
.as_mut()
.expect("rustc stdin")
.write_all(code.as_bytes())
.expect("write rustc stdin");

child.wait().expect("rustc probe").success()
}
Loading

0 comments on commit be3163a

Please sign in to comment.