Skip to content

Commit

Permalink
ThemeDefaults proof of concept
Browse files Browse the repository at this point in the history
  • Loading branch information
CosmicHorrorDev committed May 29, 2023
1 parent b521241 commit d567ad4
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 1 deletion.
79 changes: 78 additions & 1 deletion src/dumps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use std::io::{BufWriter, Write};
#[cfg(all(feature = "default-syntaxes"))]
use crate::parsing::SyntaxSet;
#[cfg(all(feature = "default-themes"))]
use crate::highlighting::ThemeSet;
use crate::highlighting::{Theme, ThemeDefaults, ThemeSet};
use std::path::Path;
#[cfg(feature = "dump-create")]
use flate2::write::ZlibEncoder;
Expand Down Expand Up @@ -208,6 +208,64 @@ impl ThemeSet {
}
}

#[cfg(feature = "default-themes")]
impl Theme {
pub fn load_default(default: ThemeDefaults) -> Self {
use std::io;

use bincode::{
config::{DefaultOptions, Options},
Deserializer,
};
use serde::{
de::{MapAccess, Visitor},
Deserializer as _,
};

// Custom themedump visitor that only returns a single theme
#[derive(Clone, Copy)]
struct ThemedumpVisitor(ThemeDefaults);

impl<'de> Visitor<'de> for ThemedumpVisitor {
type Value = Theme;

fn expecting(&self, _formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
unreachable!("has to deserialize right");
}

fn visit_map<A>(
self,
mut map: A,
) -> std::result::Result<Self::Value, <A as MapAccess<'de>>::Error>
where
A: MapAccess<'de>,
{
let theme = loop {
let name: String = map.next_key()?.expect("`default` must be in dump");

if name == self.0.as_theme_name() {
break map.next_value()?;
} else {
let _: Theme = map.next_value()?;
}
};

Ok(theme)
}
}

// Copied from the options used in `bincode::deserialize_from()`
let options = DefaultOptions::new()
.with_fixint_encoding()
.allow_trailing_bytes();
let bytes = include_bytes!("../assets/default.themedump");
let decoder = ZlibDecoder::new(io::Cursor::new(bytes));
Deserializer::with_reader(decoder, options)
.deserialize_map(ThemedumpVisitor(default))
.unwrap()
}
}

#[cfg(test)]
mod tests {
#[cfg(all(feature = "yaml-load", feature = "dump-create", feature = "dump-load", feature = "parsing"))]
Expand Down Expand Up @@ -253,4 +311,23 @@ mod tests {
let themes = ThemeSet::load_defaults();
assert!(themes.themes.len() > 4);
}

#[cfg(feature = "default-themes")]
#[test]
fn load_single_default_theme() {
use crate::highlighting::{Theme, ThemeDefaults};

for &default in &[
ThemeDefaults::Base16OceanDark,
ThemeDefaults::Base16EightiesDark,
ThemeDefaults::Base16MochaDark,
ThemeDefaults::Base16OceanLight,
ThemeDefaults::InspiredGitHub,
ThemeDefaults::SolarizedDark,
ThemeDefaults::SolarizedLight,
] {
// Ensure none of them panic
let _ = Theme::load_default(default);
}
}
}
25 changes: 25 additions & 0 deletions src/highlighting/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,28 @@ impl Default for UnderlineOption {
UnderlineOption::None
}
}

#[derive(Clone, Copy)]
pub enum ThemeDefaults {
Base16OceanDark,
Base16EightiesDark,
Base16MochaDark,
Base16OceanLight,
InspiredGitHub,
SolarizedDark,
SolarizedLight,
}

impl ThemeDefaults {
pub(crate) fn as_theme_name(self) -> &'static str {
match self {
Self::Base16OceanDark => "base16-ocean.dark",
Self::Base16EightiesDark => "base16-eighties.dark",
Self::Base16MochaDark => "base16-mocha.dark",
Self::Base16OceanLight => "base16-ocean.light",
Self::InspiredGitHub => "InspiredGitHub",
Self::SolarizedDark => "Solarized (dark)",
Self::SolarizedLight => "Solarized (light)",
}
}
}

0 comments on commit d567ad4

Please sign in to comment.