pack.rsannotatedpack.rssource83 lines · 4.1 KB · raw

The ten pack characters: friends from the pixel icon pack. Each is one nine by nine picture (the app and the page draw it, as they know its file) with a face: where its eyes are and a [MouthSpec] for its mouth, so it speaks with the same mouth the drawn characters do. This is the one list of them: their ids (which the household's document stores), their words, and their faces. A test (tests/pack.rs) holds every face to its picture: the mouth sits on the animal and never covers an eye.

7use pixel_mouth::{Grow, MouthSpec, Palette, Style};

One pack character.

10#[derive(Clone, Copy, Debug)]
11pub struct Pack {

The pack's name for the icon, which is the character's id.

13    pub id: &'static str,

The word on the picker's button.

15    pub label: &'static str,

What it is, for the picture's description.

17    pub kind: &'static str,

The cells that are its eyes (and a nose that must stay visible): no mouth covers one.

19    pub eyes: &'static [(u8, u8)],

Where its mouth is and how it is drawn, in the picture's own cells.

21    pub mouth: MouthSpec,

The pack's SVG file for the icon, exactly as the pack has it (the page draws it; the app has the same picture as pixels from whiskers-icons).

24    pub svg: &'static str,
25}
27macro_rules! icon {
28    ($name:literal) => {
29        include_str!(concat!("../../../third-party/pixel-icons/icons/", $name, ".svg"))
30    };
31}
32
33const INK: u32 = 0x343341;
34const BEAK: u32 = 0xFFB100;
35const GREY: u32 = 0xA1A0B4;
36
37const fn cells(anchor: (f32, f32), style: Style, ink: u32) -> MouthSpec {
38    MouthSpec { anchor, size: 1.0, style, palette: Palette { ink, beak: BEAK } }
39}

All ten, in the order of the chooser.

42pub const PACK: [Pack; 10] = [
43    Pack { id: "panda", label: "Panda", kind: "panda", eyes: &[(2, 2), (4, 2)], mouth: cells((3.0, 3.0), Style::Muzzle(Grow::Across), INK), svg: icon!("panda") },
44    Pack { id: "koala", label: "Koala", kind: "koala", eyes: &[(2, 5), (6, 5)], mouth: cells((4.0, 7.0), Style::Muzzle(Grow::Across), INK), svg: icon!("koala") },
45    Pack { id: "capybara", label: "Capybara", kind: "capybara", eyes: &[(4, 3)], mouth: cells((2.0, 4.0), Style::Muzzle(Grow::Down), INK), svg: icon!("capybara") },
46    Pack { id: "penguin", label: "Penguin", kind: "penguin", eyes: &[(4, 2)], mouth: cells((2.0, 2.0), Style::BeakSide, INK), svg: icon!("penguin") },
47    Pack { id: "fox", label: "Fox", kind: "fox", eyes: &[(2, 2), (4, 2)], mouth: cells((3.0, 4.0), Style::Muzzle(Grow::Down), INK), svg: icon!("fox") },
48    Pack { id: "rabbit-white", label: "Rabbit", kind: "white rabbit", eyes: &[(2, 4), (4, 4)], mouth: cells((3.0, 5.0), Style::Muzzle(Grow::Down), GREY), svg: icon!("rabbit-white") },
49    Pack { id: "owl-1", label: "Owl", kind: "owl", eyes: &[(3, 2), (5, 2)], mouth: cells((4.0, 3.0), Style::BeakFront, INK), svg: icon!("owl-1") },
50    Pack { id: "unicorn", label: "Unicorn", kind: "unicorn", eyes: &[(2, 3)], mouth: cells((2.0, 4.0), Style::Muzzle(Grow::Across), INK), svg: icon!("unicorn") },
51    Pack { id: "dog-shiba", label: "Dog", kind: "shiba dog", eyes: &[(3, 4), (5, 4)], mouth: cells((4.0, 7.0), Style::Muzzle(Grow::Across), INK), svg: icon!("dog-shiba") },
52    Pack { id: "sloth", label: "Sloth", kind: "sloth", eyes: &[(0, 4), (1, 4), (3, 4), (4, 4)], mouth: cells((2.0, 6.0), Style::Muzzle(Grow::Across), INK), svg: icon!("sloth") },
53];

The pack character called id.

56pub fn pack(id: &str) -> Option<&'static Pack> {
57    PACK.iter().find(|p| p.id == id)
58}
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[test]
65    fn every_pack_character_is_found_by_its_id() {
66        for p in PACK {
67            assert_eq!(pack(p.id).map(|x| x.id), Some(p.id));
68        }
69        assert!(pack("star").is_none());
70    }
71
72    #[test]
73    fn no_two_are_described_alike_and_no_id_repeats() {
74        let mut kinds: Vec<_> = PACK.iter().map(|p| p.kind).collect();
75        kinds.sort();
76        kinds.dedup();
77        assert_eq!(kinds.len(), PACK.len());
78        let mut ids: Vec<_> = PACK.iter().map(|p| p.id).collect();
79        ids.sort();
80        ids.dedup();
81        assert_eq!(ids.len(), PACK.len());
82    }
83}