The curated set of pixel icons Whiskers may draw for a fact, and how to read them.
The set is allowlist.txt (read it, the owner reviews it): [IconId] can only name an icon on it, so a fact
can never point at an icon that was not admitted. [raster] reads the SVG files of the vendored pack into
pixels, and [kotlin] writes them as data for the app. No I/O and no clock: it builds for wasm.
The name of an admitted icon, such as cat or birthday-cake. The only way to make one is to name an
entry of the allowlist; a name that is not admitted is an error, not an icon that fails to draw.
Why a name is not an icon Whiskers may use.
Not in the pack, or not in the shape of a name.
27 Unknown,
The admitted icon called name.
43 pub fn new(name: &str) -> Result<IconId, IconError> { 44 let list = allowlist(); 45 match list.entries().iter().find(|e| e.name == name) { 46 Some(Entry { verdict: Verdict::Admitted, name, .. }) => Ok(IconId(name)), 47 Some(_) => Err(IconError::Excluded), 48 None => Err(IconError::Unknown), 49 } 50 }
The pack's own category for this icon.
Whether the icon is a picture of a thing (an animal, a food, a toy, the weather) and not a piece of interface (an arrow, a speaker, a battery). A fact is given a picture of a thing; the interface icons are for the app's own menu.
Every admitted icon, in the order of the allowlist.
74impl fmt::Display for IconId { 75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 76 f.write_str(self.0) 77 } 78} 79 80impl<'de> Deserialize<'de> for IconId { 81 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> { 82 let name = String::deserialize(d)?; 83 IconId::new(&name).map_err(|e| serde::de::Error::custom(format!("icon: {e}"))) 84 } 85}