Today I found an implementation of is_vowel by BartMassey. It’s a much advanced implementation. I’ll try to analyze the code. Bear in mind that there is still much that I don’t know or understand.

External dependencies Link to heading

The Cargo.toml indicates that two external dependencies are used:

What is a cell-like type? See std::cell. It’s “shareable mutable container”, and the rest is a blur. I think I’ll revisit it later.

unicode-normalization provides traits to chars so they can be normalized. I’ve begin to feel that traits are indeed a smart idea. Though still lots to learn!

TODO: Read docs about std::cell and once_shell.

static or const Link to heading

Here is how the library initiate the vowels to be checked against:

static BASE_VOWELS: Lazy<HashSet<char>> = Lazy::new(|| "aeiouAEIOU".chars().collect());

Lazy is provided by once_cell that does roughly what lazy_static! macro does.

TODO: Read https://docs.rs/lazy_static/1.4.0/lazy_static/

I think I’m almost sure that a simple const would suffice. Though the author may have his reasons.

Traits Link to heading

The library implemented a trait for char that checks if it is a vowel, then added Sealed to char to prevent downstream reimplementation.

Or we could just use a simple function, like I did previously. So is traits the way?

Rust’s official blog published an article about traits. It says that traits are good for extension methods:

Traits can be used to extend an existing type (defined elsewhere) with new methods, for convenience, similarly to C#’s extension methods. This falls directly out of the scoping rules for traits: you just define the new methods in a trait, provide an implementation for the type in question, and voila, the method is available.

So I guess it means that traits is the way to go?