use crate::core::engine::EngineType;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ColorScheme {
Light,
Dark,
NoPreference,
}
impl ColorScheme {
pub fn as_str(&self) -> &'static str {
match self {
ColorScheme::Light => "light",
ColorScheme::Dark => "dark",
ColorScheme::NoPreference => "no-preference",
}
}
}
impl std::fmt::Display for ColorScheme {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_str())
}
}
impl std::str::FromStr for ColorScheme {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"light" => Ok(ColorScheme::Light),
"dark" => Ok(ColorScheme::Dark),
"no-preference" => Ok(ColorScheme::NoPreference),
_ => Err(anyhow::anyhow!(
"Invalid color scheme: \"{}\". Expected one of: light, dark, no-preference",
s
)),
}
}
}
#[derive(Debug, Clone)]
pub struct EmulateMediaOptions {
pub color_scheme: Option<ColorScheme>,
pub engine: EngineType,
}
impl EmulateMediaOptions {
pub fn new(engine: EngineType, color_scheme: Option<ColorScheme>) -> Self {
Self {
color_scheme,
engine,
}
}
pub fn dark(engine: EngineType) -> Self {
Self::new(engine, Some(ColorScheme::Dark))
}
pub fn light(engine: EngineType) -> Self {
Self::new(engine, Some(ColorScheme::Light))
}
pub fn no_preference(engine: EngineType) -> Self {
Self::new(engine, Some(ColorScheme::NoPreference))
}
pub fn reset(engine: EngineType) -> Self {
Self::new(engine, None)
}
}
pub async fn emulate_media(options: EmulateMediaOptions) -> Result<(), anyhow::Error> {
match options.engine {
EngineType::Chromiumoxide
| EngineType::Fantoccini
| EngineType::Playwright
| EngineType::Puppeteer => {
tracing::debug!(
"emulate_media: engine={}, color_scheme={:?}",
options.engine,
options.color_scheme.as_ref().map(|cs| cs.as_str())
);
Ok(())
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::str::FromStr;
#[test]
fn color_scheme_as_str() {
assert_eq!(ColorScheme::Light.as_str(), "light");
assert_eq!(ColorScheme::Dark.as_str(), "dark");
assert_eq!(ColorScheme::NoPreference.as_str(), "no-preference");
}
#[test]
fn color_scheme_display() {
assert_eq!(ColorScheme::Light.to_string(), "light");
assert_eq!(ColorScheme::Dark.to_string(), "dark");
assert_eq!(ColorScheme::NoPreference.to_string(), "no-preference");
}
#[test]
fn color_scheme_from_str_valid() {
assert_eq!(ColorScheme::from_str("light").unwrap(), ColorScheme::Light);
assert_eq!(ColorScheme::from_str("dark").unwrap(), ColorScheme::Dark);
assert_eq!(
ColorScheme::from_str("no-preference").unwrap(),
ColorScheme::NoPreference
);
}
#[test]
fn color_scheme_from_str_invalid() {
assert!(ColorScheme::from_str("invalid").is_err());
assert!(ColorScheme::from_str("").is_err());
assert!(ColorScheme::from_str("DARK").is_err());
}
#[test]
fn emulate_media_options_dark() {
let opts = EmulateMediaOptions::dark(EngineType::Chromiumoxide);
assert_eq!(opts.color_scheme, Some(ColorScheme::Dark));
assert_eq!(opts.engine, EngineType::Chromiumoxide);
}
#[test]
fn emulate_media_options_light() {
let opts = EmulateMediaOptions::light(EngineType::Chromiumoxide);
assert_eq!(opts.color_scheme, Some(ColorScheme::Light));
}
#[test]
fn emulate_media_options_no_preference() {
let opts = EmulateMediaOptions::no_preference(EngineType::Chromiumoxide);
assert_eq!(opts.color_scheme, Some(ColorScheme::NoPreference));
}
#[test]
fn emulate_media_options_reset() {
let opts = EmulateMediaOptions::reset(EngineType::Chromiumoxide);
assert_eq!(opts.color_scheme, None);
}
#[tokio::test]
async fn emulate_media_chromiumoxide() {
let opts = EmulateMediaOptions::dark(EngineType::Chromiumoxide);
assert!(emulate_media(opts).await.is_ok());
}
#[tokio::test]
async fn emulate_media_fantoccini() {
let opts = EmulateMediaOptions::light(EngineType::Fantoccini);
assert!(emulate_media(opts).await.is_ok());
}
}