fn to_voodoo_name(orig: &str, prune_p: bool) -> (String, bool, bool) {
    let mut output = String::with_capacity(48);
    let mut prev_was_new_word = true;
    let mut prev_was_uppercase = false;
    let mut first_is_p = false;
    let mut second_is_p = false;
    let mut p_was_pruned = false;
    let mut pp_was_pruned = false;
    let mut orig_pruned = orig;

    if prune_p {
        // Strip preceeding "p" or "pp" from name:
        for (char_idx, c) in orig.chars().enumerate() {
            if char_idx == 0 {
                if c == 'p' {
                    first_is_p = true;
                }
            } else if char_idx == 1 {
                if first_is_p {
                    if c.is_uppercase() {
                        orig_pruned = orig.split_at(1).1;
                        p_was_pruned = true;
                    } else if c == 'p' {
                        second_is_p = true;
                        continue;
                    }
                }
            } else if char_idx == 2 {
                if second_is_p {
                    if c.is_uppercase() {
                        orig_pruned = orig.split_at(2).1;
                        pp_was_pruned = true;
                    } else {
                        panic!("Unexpected \"pp\" at start of member name");
                    }
                }
            } else {
                break;
            }
        }
    }

    // TODO: Remove redundant checks:
    let mut char_iter = orig_pruned.chars().peekable();
    while let Some(c) = char_iter.next() {
        if c.is_lowercase() {
            output.push(c);
            prev_was_new_word = false;
            prev_was_uppercase = false;
        } else if c.is_uppercase() || c.is_numeric() {
            if prev_was_new_word {
                prev_was_new_word = false;
            } else {
                if !prev_was_uppercase {
                    output.push('_');
                } else if let Some(next_c) = char_iter.peek() {
                    if next_c.is_lowercase() {
                        output.push('_');
                    }
                }
                prev_was_new_word = true;
            }

            if c.is_uppercase() {
                output.push_str(&c.to_lowercase().to_string());
            } else {
                output.push(c);
            }
            // Consider numerics uppercase for underscore purposes:
            prev_was_uppercase = true;
        }
    }

    if output == "type_" {
        output.clear();
        output.push_str("type_of");
    }

    if PRINT { println!("{}   ->   {}", orig, &output); }
    assert!(!(p_was_pruned && pp_was_pruned));
    (output, p_was_pruned, pp_was_pruned)
}
/// Converts a pascal string to snake case and returns whether or not a "p" or
/// "pp" was pruned (indicating a pointer member).
Converts a pascal string to snake case and returns whether or not a "p" or
"pp" was pruned (indicating a pointer member).
Converts a pascal string to snake case and returns whether or not a " p " or " pp " was pruned ( indicating a pointer member ) .
fn to_voodoo_name(orig: &str, prune_p: bool) -> (String, bool, bool) {
    let mut output = String::with_capacity(48);
    let mut prev_was_new_word = true;
    let mut prev_was_uppercase = false;
    let mut first_is_p = false;
    let mut second_is_p = false;
    let mut p_was_pruned = false;
    let mut pp_was_pruned = false;
    let mut orig_pruned = orig;
    if prune_p {
        // Strip preceeding "p" or "pp" from name:
        for (char_idx, c) in orig.chars().enumerate() {
            if char_idx == 0 {
                if c == 'p' {
                    first_is_p = true;
                }
            } else if char_idx == 1 {
                if first_is_p {
                    if c.is_uppercase() {
                        orig_pruned = orig.split_at(1).1;
                        p_was_pruned = true;
                    } else if c == 'p' {
                        second_is_p = true;
                        continue;
                    }
                }
            } else if char_idx == 2 {
                if second_is_p {
                    if c.is_uppercase() {
                        orig_pruned = orig.split_at(2).1;
                        pp_was_pruned = true;
                    } else {
                        panic!("Unexpected \"pp\" at start of member name");
                    }
                }
            } else {
                break;
            }
        }
    }
    // TODO: Remove redundant checks:
    let mut char_iter = orig_pruned.chars().peekable();
    while let Some(c) = char_iter.next() {
        if c.is_lowercase() {
            output.push(c);
            prev_was_new_word = false;
            prev_was_uppercase = false;
        } else if c.is_uppercase() || c.is_numeric() {
            if prev_was_new_word {
                prev_was_new_word = false;
            } else {
                if !prev_was_uppercase {
                    output.push('_');
                } else if let Some(next_c) = char_iter.peek() {
                    if next_c.is_lowercase() {
                        output.push('_');
                    }
                }
                prev_was_new_word = true;
            }
            if c.is_uppercase() {
                output.push_str(&c.to_lowercase().to_string());
            } else {
                output.push(c);
            }
            // Consider numerics uppercase for underscore purposes:
            prev_was_uppercase = true;
        }
    }
    if output == "type_" {
        output.clear();
        output.push_str("type_of");
    }
    if PRINT { println!("{}   ->   {}", orig, &output); }
    assert!(!(p_was_pruned && pp_was_pruned));
    (output, p_was_pruned, pp_was_pruned)
}
fn to_voodoo_name ( orig : & str , prune_p : bool ) -> ( String , bool , bool ) { let mut output = String :: with_capacity ( 48 ) ; let mut prev_was_new_word = true ; let mut prev_was_uppercase = false ; let mut first_is_p = false ; let mut second_is_p = false ; let mut p_was_pruned = false ; let mut pp_was_pruned = false ; let mut orig_pruned = orig ; if prune_p { // Strip preceeding "p" or "pp" from name: for ( char_idx , c ) in orig . chars ( ) . enumerate ( ) { if char_idx == 0 { if c == 'p' { first_is_p = true ; } } else if char_idx == 1 { if first_is_p { if c . is_uppercase ( ) { orig_pruned = orig . split_at ( 1 ) . 1 ; p_was_pruned = true ; } else if c == 'p' { second_is_p = true ; continue ; } } } else if char_idx == 2 { if second_is_p { if c . is_uppercase ( ) { orig_pruned = orig . split_at ( 2 ) . 1 ; pp_was_pruned = true ; } else { panic ! ( " \" \" " ) ; } } } else { break ; } } } // TODO: Remove redundant checks: let mut char_iter = orig_pruned . chars ( ) . peekable ( ) ; while let Some ( c ) = char_iter . next ( ) { if c . is_lowercase ( ) { output . push ( c ) ; prev_was_new_word = false ; prev_was_uppercase = false ; } else if c . is_uppercase ( ) || c . is_numeric ( ) { if prev_was_new_word { prev_was_new_word = false ; } else { if ! prev_was_uppercase { output . push ( '_' ) ; } else if let Some ( next_c ) = char_iter . peek ( ) { if next_c . is_lowercase ( ) { output . push ( '_' ) ; } } prev_was_new_word = true ; } if c . is_uppercase ( ) { output . push_str ( & c . to_lowercase ( ) . to_string ( ) ) ; } else { output . push ( c ) ; } // Consider numerics uppercase for underscore purposes: prev_was_uppercase = true ; } } if output == " " { output . clear ( ) ; output . push_str ( " " ) ; } if PRINT { println ! ( " " orig output ) ; } assert ! ( ( p_was_pruned pp_was_pruned ) ) ; ( output , p_was_pruned , pp_was_pruned ) }
Converts a pascal string to snake case and returns whether or not a "p" or
"pp" was pruned (indicating a pointer member).
Converts a pascal string to snake case and returns whether or not a " p " or " pp " was pruned ( indicating a pointer member ) .
orig
&str
prune_p
bool
orig
&str
prune_p
bool