diff --git a/Cargo.toml b/Cargo.toml index b0eb120..29a3c5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,19 +8,17 @@ categories = [ "science" ] license = "MIT/Apache-2.0" name = "num-derive" repository = "https://github.com/rust-num/num-derive" -version = "0.1.44" +version = "0.2.0" readme = "README.md" [dependencies] +num-traits = "0.2" proc-macro2 = "0.2.1" quote = "0.4.2" syn = "0.12.7" [dev-dependencies] -compiletest_rs = "0.3.5" - -[dev-dependencies.num] -version = "0.1" +num = "0.1" [features] full-syntax = ["syn/full"] diff --git a/README.md b/README.md index e56540e..d2c71e4 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ Add this to your `Cargo.toml`: ```toml [dependencies] -num = "0.1" -num-derive = "0.1" +num-traits = "0.2" +num-derive = "0.2" ``` and this to your crate root: @@ -23,6 +23,17 @@ and this to your crate root: extern crate num_derive; ``` +Then you can derive traits on your own types: + +```rust +#[derive(FromPrimitive, ToPrimitive)] +enum Color { + Red, + Blue, + Green, +} +``` + ## Optional features - **`full-syntax`** — Enables `num-derive` to handle enum discriminants diff --git a/RELEASES.md b/RELEASES.md index 5785fdd..5281b1a 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,15 @@ +# Release 0.2.0 + +- [Discriminant matching is now simplified][10], casting values directly by + name, rather than trying to compute offsets from known values manually. +- **breaking change**: [Derivations now import the traits from `num-traits`][11] + instead of the full `num` crate. These are still compatible, but users need + to have an explicit `num-traits = "0.2"` dependency in their `Cargo.toml`. + +[10]: https://github.com/rust-num/num-derive/pull/10 +[11]: https://github.com/rust-num/num-derive/pull/11 + + # Release 0.1.44 - [The derived code now explicitly allows `unused_qualifications`][9], so users @@ -5,6 +17,7 @@ [9]: https://github.com/rust-num/num-derive/pull/9 + # Release 0.1.43 - [The derived code now explicitly allows `trivial_numeric_casts`][7], so users @@ -12,6 +25,7 @@ [7]: https://github.com/rust-num/num-derive/pull/7 + # Release 0.1.42 - [num-derive now has its own source repository][num-356] at [rust-num/num-derive][home]. diff --git a/ci/test_full.sh b/ci/test_full.sh index 8e59fe3..32b6c5f 100755 --- a/ci/test_full.sh +++ b/ci/test_full.sh @@ -4,13 +4,6 @@ set -ex echo Testing num-derive on rustc ${TRAVIS_RUST_VERSION} -# num-derive should build everywhere. +# num-derive should build and test everywhere. cargo build --verbose --features="$FEATURES" - -# We have no features to test... - - -if [ "$TRAVIS_RUST_VERSION" != nightly ]; then exit; fi - -# num-derive testing requires compiletest_rs, which requires nightly cargo test --verbose --features="$FEATURES" diff --git a/src/lib.rs b/src/lib.rs index 318ff38..0d56fe3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,7 +9,34 @@ // except according to those terms. #![crate_type = "proc-macro"] -#![doc(html_root_url = "https://docs.rs/num-derive/0.1")] +#![doc(html_root_url = "https://docs.rs/num-derive/0.2")] + +//! Procedural macros to derive numeric traits in Rust. +//! +//! ## Usage +//! +//! Add this to your `Cargo.toml`: +//! +//! ```toml +//! [dependencies] +//! num-traits = "0.2" +//! num-derive = "0.2" +//! ``` +//! +//! Then you can derive traits on your own types: +//! +//! ```rust +//! #[macro_use] +//! extern crate num_derive; +//! +//! #[derive(FromPrimitive, ToPrimitive)] +//! enum Color { +//! Red, +//! Blue, +//! Green, +//! } +//! # fn main() {} +//! ``` extern crate proc_macro; @@ -23,6 +50,54 @@ use proc_macro2::Span; use syn::{Data, Fields, Ident}; +/// Derives [`num_traits::FromPrimitive`][from] for simple enums. +/// +/// [from]: https://docs.rs/num-traits/0.2/num_traits/cast/trait.FromPrimitive.html +/// +/// # Examples +/// +/// Simple enums can be derived: +/// +/// ```rust +/// # #[macro_use] +/// # extern crate num_derive; +/// +/// #[derive(FromPrimitive)] +/// enum Color { +/// Red, +/// Blue, +/// Green = 42, +/// } +/// # fn main() {} +/// ``` +/// +/// Enums that contain data are not allowed: +/// +/// ```compile_fail +/// # #[macro_use] +/// # extern crate num_derive; +/// +/// #[derive(FromPrimitive)] +/// enum Color { +/// Rgb(u8, u8, u8), +/// Hsv(u8, u8, u8), +/// } +/// # fn main() {} +/// ``` +/// +/// Structs are not allowed: +/// +/// ```compile_fail +/// # #[macro_use] +/// # extern crate num_derive; +/// #[derive(FromPrimitive)] +/// struct Color { +/// r: u8, +/// g: u8, +/// b: u8, +/// } +/// # fn main() {} +/// ``` #[proc_macro_derive(FromPrimitive)] pub fn from_primitive(input: TokenStream) -> TokenStream { let ast: syn::DeriveInput = syn::parse(input).unwrap(); @@ -59,9 +134,9 @@ pub fn from_primitive(input: TokenStream) -> TokenStream { #[allow(non_upper_case_globals)] #[allow(unused_qualifications)] const #dummy_const: () = { - extern crate num as _num; + extern crate num_traits as _num_traits; - impl _num::traits::FromPrimitive for #name { + impl _num_traits::FromPrimitive for #name { #[allow(trivial_numeric_casts)] fn from_i64(#from_i64_var: i64) -> Option { #(#clauses else)* { @@ -79,6 +154,54 @@ pub fn from_primitive(input: TokenStream) -> TokenStream { res.into() } +/// Derives [`num_traits::ToPrimitive`][to] for simple enums. +/// +/// [to]: https://docs.rs/num-traits/0.2/num_traits/cast/trait.ToPrimitive.html +/// +/// # Examples +/// +/// Simple enums can be derived: +/// +/// ```rust +/// # #[macro_use] +/// # extern crate num_derive; +/// +/// #[derive(ToPrimitive)] +/// enum Color { +/// Red, +/// Blue, +/// Green = 42, +/// } +/// # fn main() {} +/// ``` +/// +/// Enums that contain data are not allowed: +/// +/// ```compile_fail +/// # #[macro_use] +/// # extern crate num_derive; +/// +/// #[derive(ToPrimitive)] +/// enum Color { +/// Rgb(u8, u8, u8), +/// Hsv(u8, u8, u8), +/// } +/// # fn main() {} +/// ``` +/// +/// Structs are not allowed: +/// +/// ```compile_fail +/// # #[macro_use] +/// # extern crate num_derive; +/// #[derive(ToPrimitive)] +/// struct Color { +/// r: u8, +/// g: u8, +/// b: u8, +/// } +/// # fn main() {} +/// ``` #[proc_macro_derive(ToPrimitive)] pub fn to_primitive(input: TokenStream) -> TokenStream { let ast: syn::DeriveInput = syn::parse(input).unwrap(); @@ -124,9 +247,9 @@ pub fn to_primitive(input: TokenStream) -> TokenStream { #[allow(non_upper_case_globals)] #[allow(unused_qualifications)] const #dummy_const: () = { - extern crate num as _num; + extern crate num_traits as _num_traits; - impl _num::traits::ToPrimitive for #name { + impl _num_traits::ToPrimitive for #name { #[allow(trivial_numeric_casts)] fn to_i64(&self) -> Option { #match_expr diff --git a/tests/compile-fail/from-primitive/derive_on_struct.rs b/tests/compile-fail/from-primitive/derive_on_struct.rs deleted file mode 100644 index 0145618..0000000 --- a/tests/compile-fail/from-primitive/derive_on_struct.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern crate num; -#[macro_use] -extern crate num_derive; - -#[derive(Debug, PartialEq, FromPrimitive)] //~ ERROR -struct Color { - r: u8, - g: u8, - b: u8, -} - -fn main() {} diff --git a/tests/compile-fail/from-primitive/enum_with_associated_data.rs b/tests/compile-fail/from-primitive/enum_with_associated_data.rs deleted file mode 100644 index ca6f34d..0000000 --- a/tests/compile-fail/from-primitive/enum_with_associated_data.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern crate num; -#[macro_use] -extern crate num_derive; - -#[derive(Debug, PartialEq, FromPrimitive)] //~ ERROR -enum Color { - Rgb(u8, u8, u8), - Hsv(u8, u8, u8), -} - -fn main() {} diff --git a/tests/compile-fail/to-primitive/derive_on_struct.rs b/tests/compile-fail/to-primitive/derive_on_struct.rs deleted file mode 100644 index 23088d0..0000000 --- a/tests/compile-fail/to-primitive/derive_on_struct.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern crate num; -#[macro_use] -extern crate num_derive; - -#[derive(Debug, PartialEq, ToPrimitive)] //~ ERROR -struct Color { - r: u8, - g: u8, - b: u8, -} - -fn main() {} diff --git a/tests/compile-fail/to-primitive/enum_with_associated_data.rs b/tests/compile-fail/to-primitive/enum_with_associated_data.rs deleted file mode 100644 index 08df949..0000000 --- a/tests/compile-fail/to-primitive/enum_with_associated_data.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern crate num; -#[macro_use] -extern crate num_derive; - -#[derive(Debug, PartialEq, ToPrimitive)] //~ ERROR -enum Color { - Rgb(u8, u8, u8), - Hsv(u8, u8, u8), -} - -fn main() {} diff --git a/tests/compiletest.rs b/tests/compiletest.rs deleted file mode 100644 index 8d87682..0000000 --- a/tests/compiletest.rs +++ /dev/null @@ -1,27 +0,0 @@ -extern crate compiletest_rs as compiletest; - -use std::path::PathBuf; -use std::env::var; - -use compiletest::Config; - -fn run_mode(mode: &'static str) { - let mut config = Config::default(); - - let cfg_mode = mode.parse().ok().expect("Invalid mode"); - - config.target_rustcflags = Some("-L target/debug/ -L target/debug/deps/".to_owned()); - if let Ok(name) = var::<&str>("TESTNAME") { - let s : String = name.to_owned(); - config.filter = Some(s) - } - config.mode = cfg_mode; - config.src_base = PathBuf::from(format!("tests/{}", mode)); - - compiletest::run_tests(&config); -} - -#[test] -fn compile_test() { - run_mode("compile-fail"); -}