#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[non_exhaustive]
pub enum ConversionMode {
#[default]
Balanced,
Strict,
Minimal,
Semantic,
Preserve,
}
impl ConversionMode {
pub fn as_str(self) -> &'static str {
match self {
Self::Balanced => "balanced",
Self::Strict => "strict",
Self::Minimal => "minimal",
Self::Semantic => "semantic",
Self::Preserve => "preserve",
}
}
pub fn parse_mode(s: &str) -> Option<Self> {
s.parse().ok()
}
}
impl std::str::FromStr for ConversionMode {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_ascii_lowercase().as_str() {
"balanced" => Ok(Self::Balanced),
"strict" => Ok(Self::Strict),
"minimal" => Ok(Self::Minimal),
"semantic" => Ok(Self::Semantic),
"preserve" => Ok(Self::Preserve),
other => Err(format!("unknown conversion mode: {other}")),
}
}
}
impl std::fmt::Display for ConversionMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone)]
pub struct ConversionOptions {
pub mode: ConversionMode,
pub preserve_ids: bool,
pub preserve_classes: bool,
pub preserve_data_attrs: bool,
pub preserve_aria_attrs: bool,
pub preserve_unknown_attrs: bool,
pub drop_presentation_attrs: bool,
pub drop_interactive_shell: bool,
pub unwrap_unknown_wrappers: bool,
}
impl Default for ConversionOptions {
fn default() -> Self {
Self::for_mode(ConversionMode::Balanced)
}
}
impl ConversionOptions {
pub fn for_mode(mode: ConversionMode) -> Self {
match mode {
ConversionMode::Balanced => Self {
mode,
preserve_ids: true, preserve_classes: false,
preserve_data_attrs: false,
preserve_aria_attrs: true,
preserve_unknown_attrs: false,
drop_presentation_attrs: true,
drop_interactive_shell: false,
unwrap_unknown_wrappers: false,
},
ConversionMode::Strict => Self {
mode,
preserve_ids: true,
preserve_classes: true,
preserve_data_attrs: true,
preserve_aria_attrs: true,
preserve_unknown_attrs: true,
drop_presentation_attrs: false,
drop_interactive_shell: false,
unwrap_unknown_wrappers: false,
},
ConversionMode::Minimal => Self {
mode,
preserve_ids: false,
preserve_classes: false,
preserve_data_attrs: false,
preserve_aria_attrs: false,
preserve_unknown_attrs: false,
drop_presentation_attrs: true,
drop_interactive_shell: true,
unwrap_unknown_wrappers: true,
},
ConversionMode::Semantic => Self {
mode,
preserve_ids: true,
preserve_classes: false,
preserve_data_attrs: false,
preserve_aria_attrs: true, preserve_unknown_attrs: false,
drop_presentation_attrs: true,
drop_interactive_shell: false,
unwrap_unknown_wrappers: true,
},
ConversionMode::Preserve => Self {
mode,
preserve_ids: true,
preserve_classes: true,
preserve_data_attrs: true,
preserve_aria_attrs: true,
preserve_unknown_attrs: true,
drop_presentation_attrs: false,
drop_interactive_shell: false,
unwrap_unknown_wrappers: false,
},
}
}
pub fn mode(mut self, mode: ConversionMode) -> Self {
self.mode = mode;
self
}
pub fn preserve_ids(mut self, v: bool) -> Self {
self.preserve_ids = v;
self
}
pub fn preserve_aria_attrs(mut self, v: bool) -> Self {
self.preserve_aria_attrs = v;
self
}
pub fn drop_interactive_shell(mut self, v: bool) -> Self {
self.drop_interactive_shell = v;
self
}
}