use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fmt;
use std::str::FromStr;
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, Default)]
pub(crate) struct AdmonitionDefaults {
#[serde(default)]
pub(crate) title: Option<String>,
#[serde(default)]
pub(crate) collapsible: bool,
#[serde(default)]
#[serde(alias = "css-id-prefix")]
pub(crate) css_id_prefix: Option<String>,
}
#[derive(Debug, PartialEq, Clone, Copy, Eq, Deserialize, Serialize, Hash)]
#[serde(rename_all = "lowercase")]
pub(crate) enum BuiltinDirective {
Note,
Abstract,
Info,
Tip,
Success,
Question,
Warning,
Failure,
Danger,
Bug,
Example,
Quote,
}
impl FromStr for BuiltinDirective {
type Err = ();
fn from_str(string: &str) -> Result<Self, ()> {
match string {
"note" => Ok(Self::Note),
"abstract" | "summary" | "tldr" => Ok(Self::Abstract),
"info" | "todo" => Ok(Self::Info),
"tip" | "hint" | "important" => Ok(Self::Tip),
"success" | "check" | "done" => Ok(Self::Success),
"question" | "help" | "faq" => Ok(Self::Question),
"warning" | "caution" | "attention" => Ok(Self::Warning),
"failure" | "fail" | "missing" => Ok(Self::Failure),
"danger" | "error" => Ok(Self::Danger),
"bug" => Ok(Self::Bug),
"example" => Ok(Self::Example),
"quote" | "cite" => Ok(Self::Quote),
_ => Err(()),
}
}
}
impl fmt::Display for BuiltinDirective {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let value = match self {
Self::Note => "note",
Self::Abstract => "abstract",
Self::Info => "info",
Self::Tip => "tip",
Self::Success => "success",
Self::Question => "question",
Self::Warning => "warning",
Self::Failure => "failure",
Self::Danger => "danger",
Self::Bug => "bug",
Self::Example => "example",
Self::Quote => "quote",
};
f.write_str(value)
}
}
#[derive(Debug, Clone)]
pub(crate) struct CustomDirective {
pub directive: String,
pub aliases: Vec<String>,
pub title: Option<String>,
pub collapsible: Option<bool>,
}
impl From<(String, crate::book_config::CustomDirective)> for CustomDirective {
fn from((directive, config): (String, crate::book_config::CustomDirective)) -> Self {
let crate::book_config::CustomDirective {
aliases,
title,
collapsible,
..
} = config;
Self {
directive,
aliases,
title,
collapsible,
}
}
}
#[derive(Debug, Clone, Default)]
pub(crate) struct CustomDirectiveMap {
inner: HashMap<String, CustomDirective>,
}
impl CustomDirectiveMap {
pub fn get(&self, key: &str) -> Option<&CustomDirective> {
self.inner.get(key)
}
}
impl FromIterator<CustomDirective> for CustomDirectiveMap {
fn from_iter<I: IntoIterator<Item = CustomDirective>>(iter: I) -> Self {
let mut inner = HashMap::default();
for config in iter.into_iter() {
inner
.entry(config.directive.clone())
.or_insert(config.clone());
for alias in config.aliases.iter() {
inner.entry(alias.clone()).or_insert(config.clone());
}
}
Self { inner }
}
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub(crate) struct BuiltinDirectiveConfig {
#[serde(default)]
pub collapsible: Option<bool>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum RenderTextMode {
Strip,
Html,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) enum CssId {
Verbatim(String),
Prefix(String),
}
#[derive(Debug, Clone, Default)]
pub(crate) struct Overrides {
pub book: AdmonitionDefaults,
pub builtin: HashMap<BuiltinDirective, BuiltinDirectiveConfig>,
pub custom: CustomDirectiveMap,
}