Basic feature flag mechanism (#5350)

This commit is contained in:
Laurenz 2024-11-01 21:02:27 +01:00 committed by GitHub
parent b357de3c48
commit fac7583745
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 61 additions and 5 deletions

View File

@ -274,8 +274,17 @@ pub struct SharedArgs {
/// defaults to number of CPUs. Setting it to 1 disables parallelism. /// defaults to number of CPUs. Setting it to 1 disables parallelism.
#[clap(long, short)] #[clap(long, short)]
pub jobs: Option<usize>, pub jobs: Option<usize>,
/// Enables in-development features that may be changed or removed at any
/// time.
#[arg(long = "feature", value_delimiter = ',')]
pub feature: Vec<Feature>,
} }
/// An in-development feature that may be changed or removed at any time.
#[derive(Debug, Copy, Clone, Eq, PartialEq, ValueEnum)]
pub enum Feature {}
/// Arguments related to where packages are stored in the system. /// Arguments related to where packages are stored in the system.
#[derive(Debug, Clone, Args)] #[derive(Debug, Clone, Args)]
pub struct PackageStorageArgs { pub struct PackageStorageArgs {

View File

@ -112,7 +112,10 @@ impl SystemWorld {
.map(|(k, v)| (k.as_str().into(), v.as_str().into_value())) .map(|(k, v)| (k.as_str().into(), v.as_str().into_value()))
.collect(); .collect();
Library::builder().with_inputs(inputs).build() let features =
command.feature.iter().map(|&feature| match feature {}).collect();
Library::builder().with_inputs(inputs).with_features(features).build()
}; };
let fonts = Fonts::searcher() let fonts = Fonts::searcher()

View File

@ -30,7 +30,7 @@ use std::ops::{Deref, Range};
use ecow::EcoString; use ecow::EcoString;
use typst_syntax::package::PackageSpec; use typst_syntax::package::PackageSpec;
use typst_syntax::{FileId, Source, Span}; use typst_syntax::{FileId, Source, Span};
use typst_utils::LazyHash; use typst_utils::{LazyHash, SmallBitSet};
use crate::diag::FileResult; use crate::diag::FileResult;
use crate::foundations::{Array, Bytes, Datetime, Dict, Module, Scope, Styles, Value}; use crate::foundations::{Array, Bytes, Datetime, Dict, Module, Scope, Styles, Value};
@ -161,9 +161,10 @@ pub struct Library {
/// The default style properties (for page size, font selection, and /// The default style properties (for page size, font selection, and
/// everything else configurable via set and show rules). /// everything else configurable via set and show rules).
pub styles: Styles, pub styles: Styles,
/// The standard library as a value. /// The standard library as a value. Used to provide the `std` variable.
/// Used to provide the `std` variable.
pub std: Value, pub std: Value,
/// In-development features that were enabled.
pub features: Features,
} }
impl Library { impl Library {
@ -186,6 +187,7 @@ impl Default for Library {
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
pub struct LibraryBuilder { pub struct LibraryBuilder {
inputs: Option<Dict>, inputs: Option<Dict>,
features: Features,
} }
impl LibraryBuilder { impl LibraryBuilder {
@ -195,16 +197,58 @@ impl LibraryBuilder {
self self
} }
/// Configure in-development features that should be enabled.
///
/// No guarantees whatsover!
pub fn with_features(mut self, features: Features) -> Self {
self.features = features;
self
}
/// Consumes the builder and returns a `Library`. /// Consumes the builder and returns a `Library`.
pub fn build(self) -> Library { pub fn build(self) -> Library {
let math = math::module(); let math = math::module();
let inputs = self.inputs.unwrap_or_default(); let inputs = self.inputs.unwrap_or_default();
let global = global(math.clone(), inputs); let global = global(math.clone(), inputs);
let std = Value::Module(global.clone()); let std = Value::Module(global.clone());
Library { global, math, styles: Styles::new(), std } Library {
global,
math,
styles: Styles::new(),
std,
features: self.features,
}
} }
} }
/// A selection of in-development features that should be enabled.
///
/// Can be collected from an iterator of [`Feature`]s.
#[derive(Debug, Default, Clone, Hash)]
pub struct Features(SmallBitSet);
impl Features {
/// Check whether the given feature is enabled.
pub fn is_enabled(&self, feature: Feature) -> bool {
self.0.contains(feature as usize)
}
}
impl FromIterator<Feature> for Features {
fn from_iter<T: IntoIterator<Item = Feature>>(iter: T) -> Self {
let mut set = SmallBitSet::default();
for feature in iter {
set.insert(feature as usize);
}
Self(set)
}
}
/// An in-development feature that should be enabled.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[non_exhaustive]
pub enum Feature {}
/// Construct the module with global definitions. /// Construct the module with global definitions.
fn global(math: Module, inputs: Dict) -> Module { fn global(math: Module, inputs: Dict) -> Module {
let mut global = Scope::deduplicating(); let mut global = Scope::deduplicating();