use crate::{version::should_enable, BrowserData, Version, Versions};
use once_cell::sync::Lazy;
use std::collections::HashMap;
use string_enum::StringEnum;
impl Feature {
pub fn should_enable(self, target: Versions, bugfixes: bool, default: bool) -> bool {
let f = if bugfixes {
&BUGFIX_FEATURES[&self]
} else {
if !FEATURES.contains_key(&self) {
return false;
}
&FEATURES[&self]
};
should_enable(target, *f, default)
}
}
#[derive(Clone, Copy, PartialEq, Eq, StringEnum, Hash)]
pub enum Feature {
TemplateLiterals,
Literals,
FunctionName,
ArrowFunctions,
BlockScopedFunctions,
Classes,
ObjectSuper,
ShorthandProperties,
DuplicateKeys,
ComputedProperties,
ForOf,
StickyRegex,
DotAllRegex,
UnicodeRegex,
Spread,
Parameters,
Destructuring,
BlockScoping,
TypeOfSymbol,
NewTarget,
Regenerator,
ExponentiationOperator,
AsyncToGenerator,
AsyncGeneratorFunctions,
ObjectRestSpread,
UnicodePropertyRegex,
JsonStrings,
OptionalCatchBinding,
NamedCapturingGroupsRegex,
MemberExpressionLiterals,
PropertyLiterals,
ReservedWords,
NullishCoalescing,
OptionalChaining,
ClassProperties,
NumericSeparator,
PrivateMethods,
UnicodeEscapes,
BugfixAsyncArrowsInClass,
BugfixEdgeDefaultParam,
BugfixTaggedTemplateCaching,
}
pub(crate) static FEATURES: Lazy<HashMap<Feature, BrowserData<Option<Version>>>> =
Lazy::new(|| {
let map: HashMap<Feature, BrowserData<Option<String>>> =
serde_json::from_str(include_str!("transform_data.json"))
.expect("failed to parse json");
map.into_iter()
.map(|(feature, version)| {
(
feature,
version.map_value(|version| version.map(|v| v.parse().unwrap())),
)
})
.collect()
});
pub(crate) static BUGFIX_FEATURES: Lazy<HashMap<Feature, BrowserData<Option<Version>>>> =
Lazy::new(|| {
let map: HashMap<Feature, BrowserData<Option<String>>> =
serde_json::from_str(include_str!("transform_data_bugfixes.json"))
.expect("failed to parse json");
FEATURES
.clone()
.into_iter()
.chain(map.into_iter().map(|(feature, version)| {
(
feature,
version.map_value(|version| version.map(|v| v.parse().unwrap())),
)
}))
.collect()
});
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn arrow() {
assert!(Feature::ArrowFunctions.should_enable(
BrowserData {
ie: Some("11.0.0".parse().unwrap()),
..Default::default()
},
false,
false
));
}
#[test]
fn tpl_lit() {
assert!(!Feature::TemplateLiterals.should_enable(
BrowserData {
chrome: Some("71.0.0".parse().unwrap()),
..Default::default()
},
false,
true
));
}
#[test]
fn tpl_lit_bugfixes() {
assert!(Feature::TemplateLiterals.should_enable(
BrowserData {
safari: Some("9.0.0".parse().unwrap()),
..Default::default()
},
false,
false
));
assert!(!Feature::BugfixTaggedTemplateCaching.should_enable(
BrowserData {
safari: Some("10.0.0".parse().unwrap()),
..Default::default()
},
false,
false
));
assert!(!Feature::TemplateLiterals.should_enable(
BrowserData {
safari: Some("9.0.0".parse().unwrap()),
..Default::default()
},
true,
false
));
assert!(Feature::BugfixTaggedTemplateCaching.should_enable(
BrowserData {
safari: Some("9.0.0".parse().unwrap()),
..Default::default()
},
true,
false
));
assert!(!Feature::BugfixTaggedTemplateCaching.should_enable(
BrowserData {
safari: Some("13.0.0".parse().unwrap()),
..Default::default()
},
true,
false
));
}
#[test]
fn edge_default_param_bug() {
assert!(Feature::Parameters.should_enable(
BrowserData {
edge: Some("17.0.0".parse().unwrap()),
..Default::default()
},
false,
false
));
assert!(!Feature::BugfixEdgeDefaultParam.should_enable(
BrowserData {
edge: Some("17.0.0".parse().unwrap()),
..Default::default()
},
false,
false
));
assert!(!Feature::Parameters.should_enable(
BrowserData {
edge: Some("17.0.0".parse().unwrap()),
..Default::default()
},
true,
false
));
assert!(Feature::BugfixEdgeDefaultParam.should_enable(
BrowserData {
edge: Some("17.0.0".parse().unwrap()),
..Default::default()
},
true,
false
));
assert!(!Feature::BugfixEdgeDefaultParam.should_enable(
BrowserData {
edge: Some("18.0.0".parse().unwrap()),
..Default::default()
},
true,
false
));
}
#[test]
fn async_arrows_in_class_bug() {
assert!(Feature::AsyncToGenerator.should_enable(
BrowserData {
safari: Some("10.1.0".parse().unwrap()),
..Default::default()
},
false,
false
));
assert!(!Feature::BugfixAsyncArrowsInClass.should_enable(
BrowserData {
safari: Some("10.1.0".parse().unwrap()),
..Default::default()
},
false,
false
));
assert!(!Feature::AsyncToGenerator.should_enable(
BrowserData {
safari: Some("10.1.0".parse().unwrap()),
..Default::default()
},
true,
false
));
assert!(Feature::BugfixAsyncArrowsInClass.should_enable(
BrowserData {
safari: Some("10.1.0".parse().unwrap()),
..Default::default()
},
true,
false
));
assert!(!Feature::BugfixAsyncArrowsInClass.should_enable(
BrowserData {
safari: Some("11.1.0".parse().unwrap()),
..Default::default()
},
true,
false
));
}
#[test]
fn block_scoping() {
assert!(Feature::BlockScoping.should_enable(
BrowserData {
safari: Some("10.0.0".parse().unwrap()),
..Default::default()
},
false,
false
));
assert!(!Feature::BlockScoping.should_enable(
BrowserData {
safari: Some("10.0.0".parse().unwrap()),
..Default::default()
},
true,
false
));
}
}