Include type information when quoting numbers

This commit is contained in:
David Tolnay 2016-09-27 09:49:59 -07:00
parent b31e2bb26d
commit 7e048938ea
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
2 changed files with 119 additions and 19 deletions

@ -51,15 +51,61 @@ macro_rules! impl_to_tokens_display {
impl_to_tokens_display!(Tokens);
impl_to_tokens_display!(bool);
impl_to_tokens_display!(i8);
impl_to_tokens_display!(i16);
impl_to_tokens_display!(i32);
impl_to_tokens_display!(i64);
impl_to_tokens_display!(isize);
impl_to_tokens_display!(u8);
impl_to_tokens_display!(u16);
impl_to_tokens_display!(u32);
impl_to_tokens_display!(u64);
impl_to_tokens_display!(usize);
impl_to_tokens_display!(f32);
impl_to_tokens_display!(f64);
macro_rules! impl_to_tokens_integer {
($ty:ty) => {
impl ToTokens for $ty {
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append(&format!(concat!("{}", stringify!($ty)), self));
}
}
};
}
impl_to_tokens_integer!(i8);
impl_to_tokens_integer!(i16);
impl_to_tokens_integer!(i32);
impl_to_tokens_integer!(i64);
impl_to_tokens_integer!(isize);
impl_to_tokens_integer!(u8);
impl_to_tokens_integer!(u16);
impl_to_tokens_integer!(u32);
impl_to_tokens_integer!(u64);
impl_to_tokens_integer!(usize);
macro_rules! impl_to_tokens_floating {
($ty:ty) => {
impl ToTokens for $ty {
fn to_tokens(&self, tokens: &mut Tokens) {
use std::num::FpCategory::*;
match self.classify() {
Zero | Subnormal | Normal => {
tokens.append(&format!(concat!("{}", stringify!($ty)), self));
}
Nan => {
tokens.append("::");
tokens.append("std");
tokens.append("::");
tokens.append(stringify!($ty));
tokens.append("::");
tokens.append("NAN");
}
Infinite => {
tokens.append("::");
tokens.append("std");
tokens.append("::");
tokens.append(stringify!($ty));
tokens.append("::");
if self.is_sign_positive() {
tokens.append("INFINITY");
} else {
tokens.append("NEG_INFINITY");
}
}
}
}
}
};
}
impl_to_tokens_floating!(f32);
impl_to_tokens_floating!(f64);

@ -1,6 +1,16 @@
use std::{f32, f64};
#[macro_use]
extern crate quote;
struct X;
impl quote::ToTokens for X {
fn to_tokens(&self, tokens: &mut quote::Tokens) {
tokens.append("X");
}
}
#[test]
fn test_quote_impl() {
let tokens = quote!(
@ -24,23 +34,23 @@ fn test_quote_impl() {
#[test]
fn test_substitution() {
let n = 1;
let tokens = quote!(#n <#n> (#n) [#n] {#n});
let x = X;
let tokens = quote!(#x <#x> (#x) [#x] {#x});
let expected = "1 < 1 > ( 1 ) [ 1 ] { 1 } ";
let expected = "X < X > ( X ) [ X ] { X } ";
assert_eq!(expected, tokens.to_string());
}
#[test]
fn test_iter() {
let primes = vec![2, 3, 5, 7];
let primes = vec![X, X, X, X];
assert_eq!("2 3 5 7 ", quote!(#(primes)*).to_string());
assert_eq!("X X X X ", quote!(#(primes)*).to_string());
assert_eq!("2 , 3 , 5 , 7 , ", quote!(#(primes,)*).to_string());
assert_eq!("X , X , X , X , ", quote!(#(primes,)*).to_string());
assert_eq!("2 , 3 , 5 , 7 ", quote!(#(primes),*).to_string());
assert_eq!("X , X , X , X ", quote!(#(primes),*).to_string());
}
#[test]
@ -97,3 +107,47 @@ fn test_advanced() {
assert_eq!(expected, tokens.to_string());
}
#[test]
fn test_integer() {
let ii8 = -1i8;
let ii16 = -1i16;
let ii32 = -1i32;
let ii64 = -1i64;
let iisize = -1isize;
let uu8 = 1u8;
let uu16 = 1u16;
let uu32 = 1u32;
let uu64 = 1u64;
let uusize = 1usize;
let tokens = quote! {
#ii8 #ii16 #ii32 #ii64 #iisize
#uu8 #uu16 #uu32 #uu64 #uusize
};
let expected = "-1i8 -1i16 -1i32 -1i64 -1isize 1u8 1u16 1u32 1u64 1usize ";
assert_eq!(expected, tokens.to_string());
}
#[test]
fn test_floating() {
let e32 = 2.71828f32;
let nan32 = f32::NAN;
let inf32 = f32::INFINITY;
let neginf32 = f32::NEG_INFINITY;
let e64 = 2.71828f64;
let nan64 = f64::NAN;
let inf64 = f64::INFINITY;
let neginf64 = f64::NEG_INFINITY;
let tokens = quote! {
#e32 @ #nan32 @ #inf32 @ #neginf32
#e64 @ #nan64 @ #inf64 @ #neginf64
};
let expected = concat!(
"2.71828f32 @ :: std :: f32 :: NAN @ :: std :: f32 :: INFINITY @ :: std :: f32 :: NEG_INFINITY ",
"2.71828f64 @ :: std :: f64 :: NAN @ :: std :: f64 :: INFINITY @ :: std :: f64 :: NEG_INFINITY ",
);
assert_eq!(expected, tokens.to_string());
}