use crate::features::{CollectedFeatures, Features, Status};
use std::collections::BTreeSet;
use std::fs;
use std::path::{Path, PathBuf};
pub const PATH_STR: &str = "doc/unstable-book";
pub const COMPILER_FLAGS_DIR: &str = "src/compiler-flags";
pub const LANG_FEATURES_DIR: &str = "src/language-features";
pub const LIB_FEATURES_DIR: &str = "src/library-features";
pub fn unstable_book_path(base_src_path: &Path) -> PathBuf {
base_src_path.join(PATH_STR)
}
pub fn unstable_book_lang_features_path(base_src_path: &Path) -> PathBuf {
unstable_book_path(base_src_path).join(LANG_FEATURES_DIR)
}
pub fn unstable_book_lib_features_path(base_src_path: &Path) -> PathBuf {
unstable_book_path(base_src_path).join(LIB_FEATURES_DIR)
}
fn dir_entry_is_file(dir_entry: &fs::DirEntry) -> bool {
dir_entry.file_type().expect("could not determine file type of directory entry").is_file()
}
pub fn collect_unstable_feature_names(features: &Features) -> BTreeSet<String> {
features
.iter()
.filter(|&(_, ref f)| f.level == Status::Unstable)
.map(|(name, _)| name.replace('_', "-"))
.collect()
}
pub fn collect_unstable_book_section_file_names(dir: &Path) -> BTreeSet<String> {
fs::read_dir(dir)
.expect("could not read directory")
.map(|entry| entry.expect("could not read directory entry"))
.filter(dir_entry_is_file)
.map(|entry| entry.path())
.filter(|path| path.extension().map(|e| e.to_str().unwrap()) == Some("md"))
.map(|path| path.file_stem().unwrap().to_str().unwrap().into())
.collect()
}
fn collect_unstable_book_lang_features_section_file_names(
base_src_path: &Path,
) -> BTreeSet<String> {
collect_unstable_book_section_file_names(&unstable_book_lang_features_path(base_src_path))
}
fn collect_unstable_book_lib_features_section_file_names(base_src_path: &Path) -> BTreeSet<String> {
collect_unstable_book_section_file_names(&unstable_book_lib_features_path(base_src_path))
}
pub fn check(path: &Path, features: CollectedFeatures, bad: &mut bool) {
let lang_features = features.lang;
let lib_features = features
.lib
.into_iter()
.filter(|&(ref name, _)| !lang_features.contains_key(name))
.collect::<Features>();
let unstable_lib_feature_names = collect_unstable_feature_names(&lib_features);
let unstable_book_lib_features_section_file_names =
collect_unstable_book_lib_features_section_file_names(path);
let unstable_lang_feature_names = collect_unstable_feature_names(&lang_features);
let unstable_book_lang_features_section_file_names =
collect_unstable_book_lang_features_section_file_names(path);
for feature_name in &unstable_book_lib_features_section_file_names - &unstable_lib_feature_names
{
if !unstable_lang_feature_names.contains(&feature_name) {
tidy_error!(
bad,
"The Unstable Book has a 'library feature' section '{}' which doesn't \
correspond to an unstable library feature",
feature_name
);
}
}
for feature_name in
&unstable_book_lang_features_section_file_names - &unstable_lang_feature_names
{
tidy_error!(
bad,
"The Unstable Book has a 'language feature' section '{}' which doesn't \
correspond to an unstable language feature",
feature_name
)
}
}