use crate::config::InstanceConfig;
use crate::types::{AdmonitionDefaults, Directive};
use std::str::FromStr;
#[derive(Debug, PartialEq)]
pub(crate) struct AdmonitionMeta {
pub directive: Directive,
pub title: String,
pub additional_classnames: Vec<String>,
pub collapsible: bool,
}
impl AdmonitionMeta {
pub fn from_info_string(
info_string: &str,
defaults: &AdmonitionDefaults,
) -> Option<Result<Self, String>> {
InstanceConfig::from_info_string(info_string)
.map(|raw| raw.map(|raw| Self::resolve(raw, defaults)))
}
fn resolve(raw: InstanceConfig, defaults: &AdmonitionDefaults) -> Self {
let InstanceConfig {
directive: raw_directive,
title,
additional_classnames,
collapsible,
} = raw;
let title = title.or_else(|| defaults.title.clone());
let collapsible = collapsible.or(defaults.collapsible).unwrap_or_default();
let (directive, title) = match (Directive::from_str(&raw_directive), title) {
(Ok(directive), None) => (directive, ucfirst(&raw_directive)),
(Err(_), None) => (Directive::Note, "Note".to_owned()),
(Ok(directive), Some(title)) => (directive, title),
(Err(_), Some(title)) => (Directive::Note, title),
};
Self {
directive,
title,
additional_classnames,
collapsible,
}
}
}
fn ucfirst(input: &str) -> String {
let mut chars = input.chars();
match chars.next() {
None => String::new(),
Some(f) => f.to_uppercase().collect::<String>() + chars.as_str(),
}
}
#[cfg(test)]
mod test {
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn test_admonition_info_from_raw() {
assert_eq!(
AdmonitionMeta::resolve(
InstanceConfig {
directive: " ".to_owned(),
title: None,
additional_classnames: Vec::new(),
collapsible: None,
},
&Default::default()
),
AdmonitionMeta {
directive: Directive::Note,
title: "Note".to_owned(),
additional_classnames: Vec::new(),
collapsible: false,
}
);
}
}