|
| 1 | +// force-host |
| 2 | +// no-prefer-dynamic |
| 3 | + |
| 4 | +#![crate_type = "proc-macro"] |
| 5 | + |
| 6 | +extern crate proc_macro; |
| 7 | +use proc_macro::{TokenStream, TokenTree as Tt}; |
| 8 | +use std::str::FromStr; |
| 9 | + |
| 10 | +// String containing the current version number of the tip, i.e. "1.41.2" |
| 11 | +static VERSION_NUMBER: &str = include_str!("../../../../../version"); |
| 12 | + |
| 13 | +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] |
| 14 | +struct Version { |
| 15 | + major: i16, |
| 16 | + minor: i16, |
| 17 | + patch: i16, |
| 18 | +} |
| 19 | + |
| 20 | +fn parse_version(s: &str) -> Option<Version> { |
| 21 | + let mut digits = s.splitn(3, '.'); |
| 22 | + let major = digits.next()?.parse().ok()?; |
| 23 | + let minor = digits.next()?.parse().ok()?; |
| 24 | + let patch = digits.next().unwrap_or("0").trim().parse().ok()?; |
| 25 | + Some(Version { major, minor, patch }) |
| 26 | +} |
| 27 | + |
| 28 | +#[proc_macro_attribute] |
| 29 | +/// Emits a #[cfg(version)] relative to the current one, so passing |
| 30 | +/// -1 as argument on compiler 1.50 will emit #[cfg(version("1.49.0"))], |
| 31 | +/// while 1 will emit #[cfg(version("1.51.0"))] |
| 32 | +pub fn ver_cfg_rel(attr: TokenStream, input: TokenStream) -> TokenStream { |
| 33 | + let mut v_rel = None; |
| 34 | + for a in attr.into_iter() { |
| 35 | + match a { |
| 36 | + Tt::Literal(l) => { |
| 37 | + let mut s = l.to_string(); |
| 38 | + let s = s.trim_matches('"'); |
| 39 | + let v: i16 = s.parse().unwrap(); |
| 40 | + v_rel = Some(v); |
| 41 | + break; |
| 42 | + }, |
| 43 | + _ => panic!("{:?}", a), |
| 44 | + } |
| 45 | + } |
| 46 | + let v_rel = v_rel.unwrap(); |
| 47 | + |
| 48 | + let mut v = parse_version(VERSION_NUMBER).unwrap(); |
| 49 | + v.minor += v_rel; |
| 50 | + |
| 51 | + let attr_str = format!("#[cfg(version(\"{}.{}.{}\"))]", v.major, v.minor, v.patch); |
| 52 | + let mut res = Vec::<Tt>::new(); |
| 53 | + res.extend(TokenStream::from_str(&attr_str).unwrap().into_iter()); |
| 54 | + res.extend(input.into_iter()); |
| 55 | + res.into_iter().collect() |
| 56 | +} |
0 commit comments