Who the demo's picker can show: the thirteen characters of the app, from the one list (whiskers_art::Character).
A closed set: a name from a visitor is parsed against it and nothing else. This adds what the page alone needs:
the default, the order of the picker (the default first), and the figure as the page's <svg id="cat">.
5use whiskers_art::{Character as Art, Drawn};
The ginger cat: the default, and first in the picker.
16 pub const DEFAULT: Character = Character(Art::Drawn(Drawn::Ginger));
Every character, in the order the picker lists them: the default first, then the app's order.
The word the page and its signals use: the app's id for the character.
What it is, for the picture's description.
A name from outside, against the closed set. Anything else is None.
Like [Character::parse] for a value that may be missing or wrong, such as a query: the
default for anything that is not a character.
The character in a mood as the page's <svg id="cat">, with the pupils bound to the pointer by
eyes_attrs (raw markup the caller writes).
58#[cfg(test)] 59mod tests { 60 use super::*; 61 62 #[test] 63 fn the_default_is_first_and_the_rest_keep_the_apps_order() { 64 let labels: Vec<_> = Character::all().iter().map(|c| c.label()).collect(); 65 assert_eq!(labels, ["Ginger", "Grey", "Bunny", "Panda", "Koala", "Capybara", "Penguin", "Fox", "Rabbit", "Owl", "Unicorn", "Dog", "Sloth"]); 66 } 67 68 #[test] 69 fn every_name_is_unique_and_round_trips_and_nothing_else_parses() { 70 let mut names: Vec<_> = Character::all().iter().map(|c| c.name()).collect(); 71 names.sort(); 72 names.dedup(); 73 assert_eq!(names.len(), 13); 74 for c in Character::all() { 75 assert_eq!(Character::parse(c.name()), Some(c)); 76 } 77 for bad in [ 78 "", "Bunny", "BUNNY", "Ginger", " bunny", "bunny ", "rabbit", "Panda", "panda ", "rabbit white", "owl", "dog", "cat", "grey", "ginger", "zebra", "whiskers", "../etc", "bunny&x=1", "grey-cat\n", "beer", "star", 79 ] { 80 assert_eq!(Character::parse(bad), None, "{bad:?}"); 81 } 82 assert_eq!(Character::parse_or_default(Some("nonsense")), Character::DEFAULT); 83 assert_eq!(Character::parse_or_default(None), Character::DEFAULT); 84 assert_eq!(Character::parse_or_default(Some("owl-1")).name(), "owl-1"); 85 assert_eq!(Character::parse_or_default(Some("bunny")).label(), "Bunny"); 86 } 87}