Skip to content

Commit 019c136

Browse files
committed
2 parents 338e479 + b7e6407 commit 019c136

9 files changed

+270
-0
lines changed

.travis/test_nightly.sh

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ set -ex
55
cargo bench --verbose
66

77
cargo test --verbose --manifest-path=macros/Cargo.toml
8+
cargo test --verbose --manifest-path=derive/Cargo.toml
89

910
# Build test for the serde feature
1011
cargo build --verbose --features "serde"

derive/Cargo.toml

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
[package]
2+
authors = ["The Rust Project Developers"]
3+
description = "Numeric syntax extensions"
4+
documentation = "http://rust-num.github.io/num"
5+
homepage = "https://github.com/rust-num/num"
6+
keywords = ["mathematics", "numerics"]
7+
license = "MIT/Apache-2.0"
8+
name = "num-derive"
9+
repository = "https://github.com/rust-num/num"
10+
version = "0.1.33"
11+
12+
[dependencies]
13+
quote = "0.1.3"
14+
syn = "0.7.0"
15+
16+
[dev-dependencies]
17+
compiletest_rs = "0.2.2"
18+
19+
[dev-dependencies.num]
20+
path = ".."
21+
version = "0.1"
22+
23+
[lib]
24+
crate-type = ["rustc-macro"]
25+
name = "num_derive"
26+
rustc-macro = true
27+
test = false

derive/src/lib.rs

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![crate_type = "rustc-macro"]
12+
#![feature(rustc_macro, rustc_macro_lib)]
13+
14+
extern crate syn;
15+
#[macro_use]
16+
extern crate quote;
17+
extern crate rustc_macro;
18+
19+
use rustc_macro::TokenStream;
20+
21+
use syn::Body::Enum;
22+
use syn::VariantData::Unit;
23+
24+
#[rustc_macro_derive(FromPrimitive)]
25+
pub fn from_primitive(input: TokenStream) -> TokenStream {
26+
let source = input.to_string();
27+
28+
let ast = syn::parse_macro_input(&source).unwrap();
29+
let name = &ast.ident;
30+
31+
let variants = match ast.body {
32+
Enum(ref variants) => variants,
33+
_ => {
34+
panic!("`FromPrimitive` can be applied only to the enums, {} is not an enum",
35+
name)
36+
}
37+
};
38+
39+
let mut idx = 0;
40+
let variants: Vec<_> = variants.iter()
41+
.map(|variant| {
42+
let ident = &variant.ident;
43+
match variant.data {
44+
Unit => (),
45+
_ => {
46+
panic!("`FromPrimitive` can be applied only to unitary enums, {}::{} is either struct or tuple", name, ident)
47+
},
48+
}
49+
if let Some(val) = variant.discriminant {
50+
idx = val.value;
51+
}
52+
let tt = quote!(#idx => Some(#name::#ident));
53+
idx += 1;
54+
tt
55+
})
56+
.collect();
57+
58+
let res = quote! {
59+
#ast
60+
61+
impl ::num::traits::FromPrimitive for #name {
62+
fn from_i64(n: i64) -> Option<Self> {
63+
Self::from_u64(n as u64)
64+
}
65+
66+
fn from_u64(n: u64) -> Option<Self> {
67+
match n {
68+
#(variants,)*
69+
_ => None,
70+
}
71+
}
72+
}
73+
};
74+
75+
res.to_string().parse().unwrap()
76+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
3+
// file at the top-level directory of this distribution and at
4+
// http://rust-lang.org/COPYRIGHT.
5+
//
6+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
7+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
8+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
9+
// option. This file may not be copied, modified, or distributed
10+
// except according to those terms.
11+
12+
#![feature(rustc_macro)]
13+
14+
extern crate num;
15+
#[macro_use]
16+
extern crate num_derive;
17+
18+
#[derive(Debug, PartialEq, FromPrimitive)] //~ ERROR
19+
struct Color {
20+
r: u8,
21+
g: u8,
22+
b: u8,
23+
}
24+
25+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
3+
// file at the top-level directory of this distribution and at
4+
// http://rust-lang.org/COPYRIGHT.
5+
//
6+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
7+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
8+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
9+
// option. This file may not be copied, modified, or distributed
10+
// except according to those terms.
11+
12+
#![feature(rustc_macro)]
13+
14+
extern crate num;
15+
#[macro_use]
16+
extern crate num_derive;
17+
18+
#[derive(Debug, PartialEq, FromPrimitive)] //~ ERROR
19+
enum Color {
20+
Rgb(u8, u8, u8),
21+
Hsv(u8, u8, u8),
22+
}
23+
24+
fn main() {}

derive/tests/compiletest.rs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
extern crate compiletest_rs as compiletest;
2+
3+
use std::path::PathBuf;
4+
use std::env::var;
5+
6+
fn run_mode(mode: &'static str) {
7+
let mut config = compiletest::default_config();
8+
9+
let cfg_mode = mode.parse().ok().expect("Invalid mode");
10+
11+
config.target_rustcflags = Some("-L target/debug/ -L target/debug/deps/".to_owned());
12+
if let Ok(name) = var::<&str>("TESTNAME") {
13+
let s : String = name.to_owned();
14+
config.filter = Some(s)
15+
}
16+
config.mode = cfg_mode;
17+
config.src_base = PathBuf::from(format!("tests/{}", mode));
18+
19+
compiletest::run_tests(&config);
20+
}
21+
22+
#[test]
23+
fn compile_test() {
24+
run_mode("compile-fail");
25+
}

derive/tests/empty_enum.rs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
3+
// file at the top-level directory of this distribution and at
4+
// http://rust-lang.org/COPYRIGHT.
5+
//
6+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
7+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
8+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
9+
// option. This file may not be copied, modified, or distributed
10+
// except according to those terms.
11+
12+
#![feature(rustc_macro)]
13+
14+
extern crate num;
15+
#[macro_use]
16+
extern crate num_derive;
17+
18+
#[derive(Debug, PartialEq, FromPrimitive)]
19+
enum Color {}
20+
21+
#[test]
22+
fn test_empty_enum() {
23+
let v: [Option<Color>; 1] = [num::FromPrimitive::from_u64(0)];
24+
25+
assert_eq!(v, [None]);
26+
}

derive/tests/trivial.rs

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(rustc_macro)]
12+
13+
extern crate num;
14+
#[macro_use]
15+
extern crate num_derive;
16+
17+
#[derive(Debug, PartialEq, FromPrimitive)]
18+
enum Color {
19+
Red,
20+
Blue,
21+
Green,
22+
}
23+
24+
#[test]
25+
fn test_from_primitive_for_trivial_case() {
26+
let v: [Option<Color>; 4] = [num::FromPrimitive::from_u64(0),
27+
num::FromPrimitive::from_u64(1),
28+
num::FromPrimitive::from_u64(2),
29+
num::FromPrimitive::from_u64(3)];
30+
31+
assert_eq!(v,
32+
[Some(Color::Red), Some(Color::Blue), Some(Color::Green), None]);
33+
}

derive/tests/with_custom_values.rs

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(rustc_macro)]
12+
13+
extern crate num;
14+
#[macro_use]
15+
extern crate num_derive;
16+
17+
#[derive(Debug, PartialEq, FromPrimitive)]
18+
enum Color {
19+
Red,
20+
Blue = 5,
21+
Green,
22+
}
23+
24+
#[test]
25+
fn test_from_primitive_for_enum_with_custom_value() {
26+
let v: [Option<Color>; 4] = [num::FromPrimitive::from_u64(0),
27+
num::FromPrimitive::from_u64(5),
28+
num::FromPrimitive::from_u64(6),
29+
num::FromPrimitive::from_u64(3)];
30+
31+
assert_eq!(v,
32+
[Some(Color::Red), Some(Color::Blue), Some(Color::Green), None]);
33+
}

0 commit comments

Comments
 (0)