use std::collections::HashMap;
use crate::model::HeadingLevel;
#[derive(Debug, Clone, Default)]
pub struct StyleMapping {
name_to_heading: HashMap<String, HeadingLevel>,
id_to_heading: HashMap<String, HeadingLevel>,
}
impl StyleMapping {
pub fn new() -> Self {
Self::default()
}
pub fn with_defaults() -> Self {
let mut mapping = Self::new();
mapping.add_name_mapping("Heading 1", HeadingLevel::H1);
mapping.add_name_mapping("Heading 2", HeadingLevel::H2);
mapping.add_name_mapping("Heading 3", HeadingLevel::H3);
mapping.add_name_mapping("Heading 4", HeadingLevel::H4);
mapping.add_name_mapping("Heading 5", HeadingLevel::H5);
mapping.add_name_mapping("Heading 6", HeadingLevel::H6);
mapping.add_name_mapping("Title", HeadingLevel::H1);
mapping.add_name_mapping("Subtitle", HeadingLevel::H2);
mapping.add_name_mapping("Chapter", HeadingLevel::H1);
mapping.add_name_mapping("제목 1", HeadingLevel::H1);
mapping.add_name_mapping("제목 2", HeadingLevel::H2);
mapping.add_name_mapping("제목 3", HeadingLevel::H3);
mapping.add_name_mapping("제목 4", HeadingLevel::H4);
mapping.add_name_mapping("제목 5", HeadingLevel::H5);
mapping.add_name_mapping("제목 6", HeadingLevel::H6);
mapping.add_name_mapping("제목1", HeadingLevel::H1);
mapping.add_name_mapping("제목2", HeadingLevel::H2);
mapping.add_name_mapping("제목3", HeadingLevel::H3);
mapping.add_name_mapping("제목4", HeadingLevel::H4);
mapping.add_name_mapping("제목5", HeadingLevel::H5);
mapping.add_name_mapping("제목6", HeadingLevel::H6);
mapping.add_id_mapping("Heading1", HeadingLevel::H1);
mapping.add_id_mapping("Heading2", HeadingLevel::H2);
mapping.add_id_mapping("Heading3", HeadingLevel::H3);
mapping.add_id_mapping("Heading4", HeadingLevel::H4);
mapping.add_id_mapping("Heading5", HeadingLevel::H5);
mapping.add_id_mapping("Heading6", HeadingLevel::H6);
mapping.add_id_mapping("Title", HeadingLevel::H1);
mapping.add_id_mapping("Subtitle", HeadingLevel::H2);
mapping
}
pub fn add_name_mapping(&mut self, name: impl Into<String>, level: HeadingLevel) {
self.name_to_heading
.insert(name.into().to_lowercase(), level);
}
pub fn add_id_mapping(&mut self, id: impl Into<String>, level: HeadingLevel) {
self.id_to_heading.insert(id.into(), level);
}
pub fn get_by_name(&self, name: &str) -> Option<HeadingLevel> {
self.name_to_heading.get(&name.to_lowercase()).copied()
}
pub fn get_by_id(&self, id: &str) -> Option<HeadingLevel> {
self.id_to_heading.get(id).copied()
}
pub fn get(&self, style_id: Option<&str>, style_name: Option<&str>) -> Option<HeadingLevel> {
if let Some(name) = style_name {
if let Some(level) = self.get_by_name(name) {
return Some(level);
}
}
if let Some(id) = style_id {
if let Some(level) = self.get_by_id(id) {
return Some(level);
}
}
None
}
pub fn is_empty(&self) -> bool {
self.name_to_heading.is_empty() && self.id_to_heading.is_empty()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_english_mappings() {
let mapping = StyleMapping::with_defaults();
assert_eq!(mapping.get_by_name("Heading 1"), Some(HeadingLevel::H1));
assert_eq!(mapping.get_by_name("heading 1"), Some(HeadingLevel::H1));
assert_eq!(mapping.get_by_name("HEADING 1"), Some(HeadingLevel::H1));
assert_eq!(mapping.get_by_name("Title"), Some(HeadingLevel::H1));
}
#[test]
fn test_default_korean_mappings() {
let mapping = StyleMapping::with_defaults();
assert_eq!(mapping.get_by_name("제목 1"), Some(HeadingLevel::H1));
assert_eq!(mapping.get_by_name("제목1"), Some(HeadingLevel::H1));
assert_eq!(mapping.get_by_name("제목 2"), Some(HeadingLevel::H2));
}
#[test]
fn test_id_mappings() {
let mapping = StyleMapping::with_defaults();
assert_eq!(mapping.get_by_id("Heading1"), Some(HeadingLevel::H1));
assert_eq!(mapping.get_by_id("Title"), Some(HeadingLevel::H1));
assert_eq!(mapping.get_by_id("Unknown"), None);
}
#[test]
fn test_combined_lookup() {
let mapping = StyleMapping::with_defaults();
assert_eq!(
mapping.get(Some("Heading1"), Some("제목 1")),
Some(HeadingLevel::H1)
);
assert_eq!(mapping.get(Some("Heading2"), None), Some(HeadingLevel::H2));
assert_eq!(mapping.get(Some("Unknown"), Some("Unknown")), None);
}
#[test]
fn test_custom_mapping() {
let mut mapping = StyleMapping::new();
mapping.add_name_mapping("Custom Title", HeadingLevel::H1);
mapping.add_id_mapping("CustomID", HeadingLevel::H3);
assert_eq!(mapping.get_by_name("custom title"), Some(HeadingLevel::H1));
assert_eq!(mapping.get_by_id("CustomID"), Some(HeadingLevel::H3));
}
}