Parse out variants from MML.

This commit is contained in:
Lyle Mantooth 2024-02-04 12:09:24 -05:00
parent 34a9821724
commit 521cacbaf4
Signed by: IslandUsurper
GPG key ID: 6DB52EAE123A5789

View file

@ -1,8 +1,65 @@
use std::collections::{BTreeMap, HashSet};
#[derive(Clone, Copy)]
pub enum SfxMode {
Off,
On,
}
struct Translation<'a> {
find: &'a str,
replacement: &'a str,
}
#[derive(Clone)]
pub struct Variant<'v> {
keep_delim: &'v str,
remove_delims: HashSet<&'v str>,
}
impl<'v> Variant<'v> {
pub fn ignores(&self) -> &HashSet<&str> {
&self.remove_delims
}
}
pub struct VariantList<'v> {
all_delims: HashSet<&'v str>,
variants: BTreeMap<&'v str, Variant<'v>>,
}
impl<'v> VariantList<'v> {
fn new() -> Self {
VariantList {
all_delims: HashSet::new(),
variants: BTreeMap::new(),
}
}
fn finish(mut self) -> Self {
for (_, v) in self.variants.iter_mut() {
v.remove_delims = self.all_delims.clone();
v.remove_delims.remove(v.keep_delim);
}
if self.variants.is_empty() {
self.variants.insert(
"_default_",
Variant {
keep_delim: "",
remove_delims: self.all_delims.clone(),
},
);
}
self
}
pub fn get(&self, name: &str) -> Option<&Variant> {
self.variants.get(name)
}
}
pub fn replace_chars(input: &str) -> String {
let trs: Vec<Translation<'_>> = input
.lines()
@ -26,3 +83,50 @@ pub fn replace_chars(input: &str) -> String {
new
}
pub fn get_variants<'a>(input: &'a str, sfx_mode: SfxMode) -> VariantList<'a> {
input
.lines()
.fold(VariantList::new(), |mut state, line| {
if let Some(l) = line.strip_prefix("#SFXV") {
if let Some((first, second)) = l.trim().rsplit_once(' ') {
use SfxMode::*;
match sfx_mode {
Off => state.all_delims.insert(first),
On => state.all_delims.insert(second),
};
}
} else if let Some(l) = line.strip_prefix("#VARIANT") {
let (first, second) = {
let rest = l.trim();
if let Some((f, s)) = rest.rsplit_once(' ') {
(f, s)
} else {
(rest, "_default_")
}
};
state.all_delims.insert(first);
if state.variants.len() == 0 && second != "_default_" {
state.variants.insert(
"_default_",
Variant {
keep_delim: first,
remove_delims: HashSet::new(),
},
);
}
state.variants.insert(
second,
Variant {
keep_delim: first,
remove_delims: HashSet::new(),
},
);
}
state
})
.finish()
}