use super::FeatureCategory;
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
pub struct Feature
{
pub name: &'static str,
pub categories: &'static [FeatureCategory],
pub probe: Probe,
}
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
pub enum Probe
{
Expr(&'static str),
Type(&'static str),
Path(&'static str),
AlwaysEnabled,
UnstableFeatures,
}
const DEFINITION: &'static [Feature] = &[
Feature {
name: "arbitrary_self_types",
categories: &["lang"],
probe: Probe::Expr(
r#"{
struct Thing;
struct Wrap<T: ?Sized>(T);
impl<T: ?Sized> std::ops::Deref for Wrap<T> {
type Target = T;
fn deref(&self) -> &Self::Target { &self.0 }
}
trait WrapSelf { fn m(self: Wrap<Self>); }
impl WrapSelf for Thing { fn m(self: Wrap<Self>) {} }
Wrap(Thing).m()
}"#,
),
},
Feature {
name: "cfg_version",
categories: &["lang"],
probe: Probe::Expr(r#"{ #[cfg(version("1.0"))] struct X; X }"#),
},
Feature {
name: "destructuring_assignment",
categories: &["lang"],
probe: Probe::Expr("{ let (_a, _b); (_a, _b) = (1, 2); }"),
},
Feature {
name: "error_in_core",
categories: &["lib"],
probe: Probe::Expr("{ let _: &core::error::Error; }"),
},
Feature {
name: "inner_deref",
categories: &["lib"],
probe: Probe::Expr("Ok::<_, ()>(vec![1]).as_deref()"),
},
Feature {
name: "iter_zip",
categories: &["lib"],
probe: Probe::Path("std::iter::zip"),
},
Feature { name: "never_type", categories: &["lang"], probe: Probe::Type("!") },
Feature {
name: "question_mark",
categories: &["lang"],
probe: Probe::Expr("|| -> Result<(), ()> { Err(())? }"),
},
Feature {
name: "rust1",
categories: &["comp", "lang", "lib"],
probe: Probe::AlwaysEnabled,
},
Feature {
name: "step_trait",
categories: &["lib"],
probe: Probe::Path("std::iter::Step"),
},
Feature {
name: "unstable_features",
categories: &["comp"],
probe: Probe::UnstableFeatures,
},
Feature {
name: "unwrap_infallible",
categories: &["lib"],
probe: Probe::Expr("Ok::<(), !>(()).into_ok()"),
},
];
pub fn get(feature_name: &str) -> Option<&'static Feature>
{
DEFINITION
.binary_search_by(|element| element.name.cmp(feature_name))
.ok()
.map(|index| &DEFINITION[index])
}
#[cfg(test)]
mod tests
{
use super::{Feature, DEFINITION};
fn sorted() -> Vec<Feature>
{
let mut v = Vec::from(DEFINITION);
v.sort_by(|a, b| a.name.cmp(b.name));
v
}
#[test]
fn no_duplicates()
{
let mut deduped = sorted();
deduped.dedup();
assert_eq!(DEFINITION, &*deduped);
}
#[test]
fn is_sorted()
{
assert_eq!(DEFINITION, &*sorted());
}
}