use std::str::FromStr;
use serde::Deserialize;
use crate::DEFAULT_THEME;
pub(crate) trait Merge {
fn merge(self, other: Self) -> Self;
}
fn merge_opts<M: Merge>(a: Option<M>, b: Option<M>) -> Option<M> {
match (a, b) {
(Some(a), Some(b)) => Some(a.merge(b)),
(None, Some(b)) => Some(b),
(Some(a), None) => Some(a),
_ => None,
}
}
#[derive(Debug)]
pub(crate) struct Config {
pub roxy: RoxyConfig,
pub syntect: SyntectConfig
}
impl From<ConfigDeserializer> for Config {
fn from(value: ConfigDeserializer) -> Self {
Self {
roxy: value.roxy.map_or_else(Default::default, From::from),
syntect: value.syntect.map_or_else(Default::default, From::from)
}
}
}
#[derive(Debug)]
pub(crate) struct RoxyConfig {
pub slug_word_limit: usize
}
impl From<RoxyConfigDeserializer> for RoxyConfig {
fn from(value: RoxyConfigDeserializer) -> Self {
Self {
slug_word_limit: value.slug_word_limit.unwrap_or(24usize)
}
}
}
impl Default for RoxyConfig {
fn default() -> Self {
Self {
slug_word_limit: 24usize
}
}
}
#[derive(Debug)]
pub(crate) struct SyntectConfig {
pub theme: String,
pub theme_dir: Option<String>
}
impl From<SyntectConfigDeserializer> for SyntectConfig {
fn from(value: SyntectConfigDeserializer) -> Self {
Self {
theme: value.theme.unwrap_or(DEFAULT_THEME.into()),
theme_dir: value.theme_dir
}
}
}
impl Default for SyntectConfig {
fn default() -> Self {
Self {
theme: DEFAULT_THEME.into(),
theme_dir: None
}
}
}
#[derive(Debug, Default, Deserialize)]
pub(crate) struct ConfigDeserializer {
pub roxy: Option<RoxyConfigDeserializer>,
pub syntect: Option<SyntectConfigDeserializer>,
}
impl FromStr for ConfigDeserializer {
type Err = toml::de::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
toml::from_str(s)
}
}
impl Merge for ConfigDeserializer {
fn merge(self, other: Self) -> Self {
Self {
roxy: merge_opts(self.roxy, other.roxy),
syntect: merge_opts(self.syntect, other.syntect),
}
}
}
#[derive(Debug, Deserialize)]
pub(crate) struct RoxyConfigDeserializer {
pub slug_word_limit: Option<usize>,
}
impl Default for RoxyConfigDeserializer {
fn default() -> Self {
Self {
slug_word_limit: Some(8usize),
}
}
}
impl Merge for RoxyConfigDeserializer {
fn merge(self, other: Self) -> Self {
Self {
slug_word_limit: self.slug_word_limit.or(other.slug_word_limit),
}
}
}
#[derive(Debug, Default, Deserialize)]
pub(crate) struct SyntectConfigDeserializer {
pub theme: Option<String>,
pub theme_dir: Option<String>,
}
impl Merge for SyntectConfigDeserializer {
fn merge(self, other: SyntectConfigDeserializer) -> Self {
Self {
theme: self.theme.or(other.theme),
theme_dir: self.theme_dir.or(other.theme_dir),
}
}
}