Compare commits
	
		
			No commits in common. "ef9b4f3769119b6f320e8a64bfe618ad93db103a" and "3018db7dd1507249900e31c27e484d6fb7422685" have entirely different histories.
		
	
	
		
			ef9b4f3769
			...
			3018db7dd1
		
	
		
					 2 changed files with 16 additions and 55 deletions
				
			
		| 
						 | 
				
			
			@ -64,7 +64,9 @@ fn wave_numbers(input: &str) -> IResult<&str, (usize, u8)> {
 | 
			
		|||
                })
 | 
			
		||||
        }),
 | 
			
		||||
        space1,
 | 
			
		||||
        map_res(hexordecimal, |(radix, s)| u8::from_str_radix(s, radix)),
 | 
			
		||||
        map_res(hexordecimal, |(radix, s)| {
 | 
			
		||||
            u8::from_str_radix(s, radix)
 | 
			
		||||
        }),
 | 
			
		||||
    )(input)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										67
									
								
								src/mfvi.rs
									
										
									
									
									
								
							
							
						
						
									
										67
									
								
								src/mfvi.rs
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -14,22 +14,22 @@ struct Translation<'a> {
 | 
			
		|||
 | 
			
		||||
#[derive(Clone)]
 | 
			
		||||
/// Holds the set of delimiters that should be removed from the MML to select a variant.
 | 
			
		||||
pub struct Variant {
 | 
			
		||||
    keep_delim: char,
 | 
			
		||||
    remove_delims: HashSet<char>,
 | 
			
		||||
pub struct Variant<'v> {
 | 
			
		||||
    keep_delim: &'v str,
 | 
			
		||||
    remove_delims: HashSet<&'v str>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Variant {
 | 
			
		||||
impl<'v> Variant<'v> {
 | 
			
		||||
    /// Get the set of character delimiters to remove from MML for this variant.
 | 
			
		||||
    pub fn ignores(&self) -> &HashSet<char> {
 | 
			
		||||
    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<char>,
 | 
			
		||||
    variants: BTreeMap<&'v str, Variant>,
 | 
			
		||||
    all_delims: HashSet<&'v str>,
 | 
			
		||||
    variants: BTreeMap<&'v str, Variant<'v>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'v> VariantList<'v> {
 | 
			
		||||
| 
						 | 
				
			
			@ -43,16 +43,14 @@ impl<'v> VariantList<'v> {
 | 
			
		|||
    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);
 | 
			
		||||
            v.remove_delims.remove(v.keep_delim);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if self.variants.is_empty() {
 | 
			
		||||
            self.variants.insert(
 | 
			
		||||
                "_default_",
 | 
			
		||||
                Variant {
 | 
			
		||||
                    // Not that we expect to find NUL bytes, but effectively we will remove all
 | 
			
		||||
                    // delimiters with this variant.
 | 
			
		||||
                    keep_delim: '\0',
 | 
			
		||||
                    keep_delim: "",
 | 
			
		||||
                    remove_delims: self.all_delims.clone(),
 | 
			
		||||
                },
 | 
			
		||||
            );
 | 
			
		||||
| 
						 | 
				
			
			@ -117,17 +115,17 @@ pub fn get_variants<'a>(input: &'a str, sfx_mode: SfxMode) -> VariantList<'a> {
 | 
			
		|||
                if let Some((first, second)) = l.trim().rsplit_once(char::is_whitespace) {
 | 
			
		||||
                    use SfxMode::*;
 | 
			
		||||
                    match sfx_mode {
 | 
			
		||||
                        Off => state.all_delims.insert(first_char(first)),
 | 
			
		||||
                        On => state.all_delims.insert(first_char(second)),
 | 
			
		||||
                        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(' ') {
 | 
			
		||||
                        (first_char(f), s)
 | 
			
		||||
                        (f, s)
 | 
			
		||||
                    } else {
 | 
			
		||||
                        (first_char(rest), "_default_")
 | 
			
		||||
                        (rest, "_default_")
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -155,42 +153,3 @@ pub fn get_variants<'a>(input: &'a str, sfx_mode: SfxMode) -> VariantList<'a> {
 | 
			
		|||
        })
 | 
			
		||||
        .finish()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn first_char(s: &str) -> char {
 | 
			
		||||
    s.chars().next().unwrap_or('\0')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn select_variant<'i>(input: &'i str, var: &'i Variant) -> String {
 | 
			
		||||
    let mut output = input.to_string();
 | 
			
		||||
    // Workspace for converting char to &str in the loop.
 | 
			
		||||
    let mut buf = [0; 4];
 | 
			
		||||
    // Set of chars to find in `input`.
 | 
			
		||||
    let charlist: Vec<char> = var
 | 
			
		||||
        .remove_delims
 | 
			
		||||
        .iter()
 | 
			
		||||
        .copied()
 | 
			
		||||
        .chain([var.keep_delim])
 | 
			
		||||
        .collect();
 | 
			
		||||
    let mut needles = input.rmatch_indices(&charlist[..]).peekable();
 | 
			
		||||
 | 
			
		||||
    while let Some((idx, c)) = needles.next() {
 | 
			
		||||
        match c {
 | 
			
		||||
            // Remove the char if it is the `keep_delim`.
 | 
			
		||||
            d if var.keep_delim.encode_utf8(&mut buf) == d => {
 | 
			
		||||
                // `replace_range` doesn't make a full copy of the string the way `remove` does.
 | 
			
		||||
                output.replace_range(idx..=idx, "");
 | 
			
		||||
            }
 | 
			
		||||
            // Anything else will be in `remove_delim`, so find a matching pair and remove
 | 
			
		||||
            // them and everything between them.
 | 
			
		||||
            d => match needles.peek() {
 | 
			
		||||
                Some(&(idx_1, d2)) if d == d2 => {
 | 
			
		||||
                    needles.next();
 | 
			
		||||
                    output.replace_range(idx_1..=idx, "");
 | 
			
		||||
                }
 | 
			
		||||
                _ => {}
 | 
			
		||||
            },
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    output
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue