use std::time::Duration;
pub const DEFAULT_FALLBACK_TIMEOUT: Duration = Duration::from_millis(32);
#[derive(Debug, Clone)]
pub struct AppConfig {
allow_software_fallback: bool,
fallback_timeout: Duration,
prefer_cpu: bool,
}
impl AppConfig {
#[must_use]
pub fn allow_software_fallback(&self) -> bool {
self.allow_software_fallback
}
#[must_use]
pub fn fallback_timeout(&self) -> Duration {
self.fallback_timeout
}
#[must_use]
pub fn prefer_cpu(&self) -> bool {
self.prefer_cpu
}
}
impl Default for AppConfig {
fn default() -> Self {
Self {
allow_software_fallback: false,
fallback_timeout: DEFAULT_FALLBACK_TIMEOUT,
prefer_cpu: false,
}
}
}
impl From<AppConfig> for martensite_wgpu::OrchestratorConfig {
fn from(config: AppConfig) -> Self {
Self {
allow_software_fallback: config.allow_software_fallback,
prefer_cpu: config.prefer_cpu,
}
}
}
#[derive(Debug, Clone)]
pub struct AppBuilder {
config: AppConfig,
}
impl AppBuilder {
#[must_use]
pub fn allow_software_fallback(mut self, allow: bool) -> Self {
self.config.allow_software_fallback = allow;
self
}
#[must_use]
pub fn fallback_timeout(mut self, timeout: Duration) -> Self {
self.config.fallback_timeout = timeout;
self
}
#[must_use]
pub fn prefer_cpu(mut self, prefer: bool) -> Self {
self.config.prefer_cpu = prefer;
self
}
#[must_use]
pub fn build(self) -> AppConfig {
self.config
}
}
pub struct App;
impl App {
#[must_use]
pub fn build() -> AppBuilder {
AppBuilder {
config: AppConfig::default(),
}
}
}
#[cfg(test)]
mod tests {
use super::{App, AppConfig, DEFAULT_FALLBACK_TIMEOUT};
use std::time::Duration;
#[test]
fn default_config_disallows_software_fallback() {
let config = AppConfig::default();
assert!(!config.allow_software_fallback());
}
#[test]
fn default_config_has_32ms_timeout() {
let config = AppConfig::default();
assert_eq!(config.fallback_timeout(), DEFAULT_FALLBACK_TIMEOUT);
assert_eq!(config.fallback_timeout(), Duration::from_millis(32));
}
#[test]
fn default_config_does_not_prefer_cpu() {
let config = AppConfig::default();
assert!(!config.prefer_cpu());
}
#[test]
fn build_returns_app_builder() {
let _builder = App::build();
}
#[test]
fn allow_software_fallback_enables_it() {
let config = App::build().allow_software_fallback(true).build();
assert!(config.allow_software_fallback());
}
#[test]
fn allow_software_fallback_false_disables_it() {
let config = App::build().allow_software_fallback(false).build();
assert!(!config.allow_software_fallback());
}
#[test]
fn fallback_timeout_sets_custom_duration() {
let config = App::build()
.fallback_timeout(Duration::from_millis(100))
.build();
assert_eq!(config.fallback_timeout(), Duration::from_millis(100));
}
#[test]
fn prefer_cpu_enables_cpu_preference() {
let config = App::build().prefer_cpu(true).build();
assert!(config.prefer_cpu());
}
#[test]
fn builder_chains_multiple_options() {
let config = App::build()
.allow_software_fallback(true)
.fallback_timeout(Duration::from_millis(50))
.prefer_cpu(true)
.build();
assert!(config.allow_software_fallback());
assert_eq!(config.fallback_timeout(), Duration::from_millis(50));
assert!(config.prefer_cpu());
}
#[test]
fn builder_is_cloneable() {
let builder = App::build().allow_software_fallback(true);
let cloned = builder.clone();
assert!(cloned.build().allow_software_fallback());
}
#[test]
fn config_is_cloneable() {
let config = App::build().allow_software_fallback(true).build();
let cloned = config.clone();
assert!(cloned.allow_software_fallback());
}
#[test]
fn app_config_converts_to_orchestrator_config() {
let config = App::build()
.allow_software_fallback(true)
.prefer_cpu(true)
.build();
let orchestrator_config: martensite_wgpu::OrchestratorConfig = config.into();
assert!(orchestrator_config.allow_software_fallback);
assert!(orchestrator_config.prefer_cpu);
}
#[test]
fn default_app_config_converts_to_default_orchestrator_config() {
let config = AppConfig::default();
let orchestrator_config: martensite_wgpu::OrchestratorConfig = config.into();
assert!(!orchestrator_config.allow_software_fallback);
assert!(!orchestrator_config.prefer_cpu);
}
}