pub(crate) fn is_built_in_context(context: &str) -> bool {
BuiltInContext::from_str(context).is_some()
}
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
#[non_exhaustive]
pub enum BuiltInContext {
Admonition,
Audio,
Colist,
Dlist,
Document,
Example,
FloatingTitle,
Image,
ListItem,
Listing,
Literal,
Olist,
Open,
PageBreak,
Paragraph,
Pass,
Preamble,
Quote,
Section,
Sidebar,
Stem,
Table,
TableCell,
ThematicBreak,
Toc,
Ulist,
Verse,
Video,
}
impl BuiltInContext {
pub const ALL: &'static [BuiltInContext] = &[
Self::Admonition,
Self::Audio,
Self::Colist,
Self::Dlist,
Self::Document,
Self::Example,
Self::FloatingTitle,
Self::Image,
Self::ListItem,
Self::Listing,
Self::Literal,
Self::Olist,
Self::Open,
Self::PageBreak,
Self::Paragraph,
Self::Pass,
Self::Preamble,
Self::Quote,
Self::Section,
Self::Sidebar,
Self::Stem,
Self::Table,
Self::TableCell,
Self::ThematicBreak,
Self::Toc,
Self::Ulist,
Self::Verse,
Self::Video,
];
pub fn as_str(self) -> &'static str {
match self {
Self::Admonition => "admonition",
Self::Audio => "audio",
Self::Colist => "colist",
Self::Dlist => "dlist",
Self::Document => "document",
Self::Example => "example",
Self::FloatingTitle => "floating_title",
Self::Image => "image",
Self::ListItem => "list_item",
Self::Listing => "listing",
Self::Literal => "literal",
Self::Olist => "olist",
Self::Open => "open",
Self::PageBreak => "page_break",
Self::Paragraph => "paragraph",
Self::Pass => "pass",
Self::Preamble => "preamble",
Self::Quote => "quote",
Self::Section => "section",
Self::Sidebar => "sidebar",
Self::Stem => "stem",
Self::Table => "table",
Self::TableCell => "table_cell",
Self::ThematicBreak => "thematic_break",
Self::Toc => "toc",
Self::Ulist => "ulist",
Self::Verse => "verse",
Self::Video => "video",
}
}
#[allow(clippy::should_implement_trait)]
pub fn from_str(context: &str) -> Option<Self> {
Some(match context {
"admonition" => Self::Admonition,
"audio" => Self::Audio,
"colist" => Self::Colist,
"dlist" => Self::Dlist,
"document" => Self::Document,
"example" => Self::Example,
"floating_title" => Self::FloatingTitle,
"image" => Self::Image,
"list_item" => Self::ListItem,
"listing" => Self::Listing,
"literal" => Self::Literal,
"olist" => Self::Olist,
"open" => Self::Open,
"page_break" => Self::PageBreak,
"paragraph" => Self::Paragraph,
"pass" => Self::Pass,
"preamble" => Self::Preamble,
"quote" => Self::Quote,
"section" => Self::Section,
"sidebar" => Self::Sidebar,
"stem" => Self::Stem,
"table" => Self::Table,
"table_cell" => Self::TableCell,
"thematic_break" => Self::ThematicBreak,
"toc" => Self::Toc,
"ulist" => Self::Ulist,
"verse" => Self::Verse,
"video" => Self::Video,
_ => return None,
})
}
}
impl std::fmt::Debug for BuiltInContext {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "BuiltInContext::{}", {
match self {
Self::Admonition => "Admonition",
Self::Audio => "Audio",
Self::Colist => "Colist",
Self::Dlist => "Dlist",
Self::Document => "Document",
Self::Example => "Example",
Self::FloatingTitle => "FloatingTitle",
Self::Image => "Image",
Self::ListItem => "ListItem",
Self::Listing => "Listing",
Self::Literal => "Literal",
Self::Olist => "Olist",
Self::Open => "Open",
Self::PageBreak => "PageBreak",
Self::Paragraph => "Paragraph",
Self::Pass => "Pass",
Self::Preamble => "Preamble",
Self::Quote => "Quote",
Self::Section => "Section",
Self::Sidebar => "Sidebar",
Self::Stem => "Stem",
Self::Table => "Table",
Self::TableCell => "TableCell",
Self::ThematicBreak => "ThematicBreak",
Self::Toc => "Toc",
Self::Ulist => "Ulist",
Self::Verse => "Verse",
Self::Video => "Video",
}
})
}
}
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum AdmonitionVariant {
Note,
Tip,
Important,
Caution,
Warning,
}
impl AdmonitionVariant {
pub(crate) fn from_style(style: &str) -> Option<Self> {
Some(match style {
"NOTE" => Self::Note,
"TIP" => Self::Tip,
"IMPORTANT" => Self::Important,
"CAUTION" => Self::Caution,
"WARNING" => Self::Warning,
_ => return None,
})
}
pub fn style(self) -> &'static str {
match self {
Self::Note => "NOTE",
Self::Tip => "TIP",
Self::Important => "IMPORTANT",
Self::Caution => "CAUTION",
Self::Warning => "WARNING",
}
}
pub fn name(self) -> &'static str {
match self {
Self::Note => "note",
Self::Tip => "tip",
Self::Important => "important",
Self::Caution => "caution",
Self::Warning => "warning",
}
}
pub fn default_caption(self) -> &'static str {
match self {
Self::Note => "Note",
Self::Tip => "Tip",
Self::Important => "Important",
Self::Caution => "Caution",
Self::Warning => "Warning",
}
}
}
impl std::fmt::Debug for AdmonitionVariant {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Note => write!(f, "AdmonitionVariant::Note"),
Self::Tip => write!(f, "AdmonitionVariant::Tip"),
Self::Important => write!(f, "AdmonitionVariant::Important"),
Self::Caution => write!(f, "AdmonitionVariant::Caution"),
Self::Warning => write!(f, "AdmonitionVariant::Warning"),
}
}
}
#[cfg(test)]
mod tests {
mod built_in_context {
use crate::blocks::{BuiltInContext, context::is_built_in_context};
#[test]
fn round_trips_every_variant() {
for &context in BuiltInContext::ALL {
assert_eq!(BuiltInContext::from_str(context.as_str()), Some(context));
assert!(is_built_in_context(context.as_str()));
}
}
#[test]
fn all_is_complete_and_deduplicated() {
assert_eq!(BuiltInContext::ALL.len(), 28);
let mut seen: Vec<&str> = BuiltInContext::ALL.iter().map(|c| c.as_str()).collect();
seen.sort_unstable();
seen.dedup();
assert_eq!(seen.len(), BuiltInContext::ALL.len());
}
#[test]
fn known_contexts() {
assert_eq!(
BuiltInContext::from_str("paragraph"),
Some(BuiltInContext::Paragraph)
);
assert_eq!(BuiltInContext::Listing.as_str(), "listing");
assert_eq!(BuiltInContext::TableCell.as_str(), "table_cell");
}
#[test]
fn unknown_context_is_none() {
assert_eq!(BuiltInContext::from_str("verbatim"), None);
assert_eq!(BuiltInContext::from_str("Paragraph"), None);
assert!(!is_built_in_context("not-a-context"));
}
#[test]
fn impl_debug() {
assert_eq!(
format!("{:?}", BuiltInContext::FloatingTitle),
"BuiltInContext::FloatingTitle"
);
let mut seen = std::collections::HashSet::new();
for &context in BuiltInContext::ALL {
let debug = format!("{context:?}");
assert!(debug.starts_with("BuiltInContext::"));
assert!(!debug.contains(' '));
assert!(seen.insert(debug), "duplicate Debug rendering");
}
assert_eq!(seen.len(), BuiltInContext::ALL.len());
}
}
}