Add documentation of public items.

This commit is contained in:
Lyle Mantooth 2024-02-04 13:43:56 -05:00
parent 521cacbaf4
commit 209d1db66e
Signed by: IslandUsurper
GPG key ID: 6DB52EAE123A5789

View file

@ -1,6 +1,7 @@
use std::collections::{BTreeMap, HashSet};
#[derive(Clone, Copy)]
/// Flag indicating whether special effects variants should be used.
pub enum SfxMode {
Off,
On,
@ -12,17 +13,20 @@ struct Translation<'a> {
}
#[derive(Clone)]
/// Holds the set of delimiters that should be removed from the MML to select a variant.
pub struct Variant<'v> {
keep_delim: &'v str,
remove_delims: HashSet<&'v str>,
}
impl<'v> Variant<'v> {
/// Get the set of character delimiters to remove from MML for this variant.
pub fn ignores(&self) -> &HashSet<&str> {
&self.remove_delims
}
}
/// The list of all variants defined in an MML file.
pub struct VariantList<'v> {
all_delims: HashSet<&'v str>,
variants: BTreeMap<&'v str, Variant<'v>>,
@ -55,17 +59,26 @@ impl<'v> VariantList<'v> {
self
}
/// Get a specific variant by name, which exists in the MML file.
pub fn get(&self, name: &str) -> Option<&Variant> {
self.variants.get(name)
}
}
/// Processes "#REPLACE" macros in MML.
///
/// Macro syntax:
/// #REPLACE c1 c2
///
/// "c1" and "c2" are meant to be single characters, but `replace_chars` finds any two strings of
/// non-whitespace. These strings are substituted in-place, so the longer string is truncated to
/// the length of the shorter.
pub fn replace_chars(input: &str) -> String {
let trs: Vec<Translation<'_>> = input
.lines()
.filter_map(|line| {
line.strip_prefix("#REPLACE")
.and_then(|l| l.trim().rsplit_once(' '))
.and_then(|l| l.trim().rsplit_once(char::is_whitespace))
.and_then(|(first, second)| {
let length = std::cmp::min(first.len(), second.len());
Some(Translation {
@ -84,12 +97,22 @@ pub fn replace_chars(input: &str) -> String {
new
}
/// Processes "#SFXV" and "#VARIANT" macros in MML.
///
/// Macro syntax:
/// #SFXV o i
/// #VARIANT c name
///
/// "o", "i", and "c" are single characters that act as markup delimiters around the variant codes.
/// For #SFXV, if special effects mode is off, the "o" variants are used, otherwise "i". The "name"
/// for one #VARIANT is optional, and its absence indicates the default variant. If all variants in
/// the input are named, the first variant will be the default.
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(' ') {
if let Some((first, second)) = l.trim().rsplit_once(char::is_whitespace) {
use SfxMode::*;
match sfx_mode {
Off => state.all_delims.insert(first),