Skip to main content

yog_data/image/
mod.rs

1//! [`Image`]: a picture a screen shows.
2
3use substrate_data::schema::NamedType;
4use substrate_data::typed::{Spelled, classify};
5use substrate_data::{Id, Kind, Ref, Value};
6
7use crate::{Res, kinds};
8
9/// An image: a source (`@image:sprite:button`, `@image:mymod:gui/logo`,
10/// `@image:item:minecraft:stick`) or a `.yres` image (`@res:Images.logo`).
11#[derive(Debug, Clone, PartialEq)]
12pub enum Image {
13    Source(String),
14    Res(Res),
15}
16
17impl Image {
18    /// What reference `r` is as an image.
19    fn of_ref(r: &Ref) -> Option<Image> {
20        let (kind, id) = (r.kind.as_str(), r.id.as_str());
21        if kind == kinds::Res::NAME {
22            return Res::parse(id).map(Image::Res);
23        }
24        (kind == kinds::Image::NAME).then(|| Image::Source(id.to_owned()))
25    }
26}
27
28impl NamedType for Image {
29    const NAME: &'static str = yog_ids::typed::IMAGE;
30    type Stored = Value;
31    fn to_stored(&self) -> Value {
32        match self {
33            Image::Source(s) => substrate_data::Schema::write(&Id::<kinds::Image>::new(s.clone())),
34            Image::Res(r) => substrate_data::Schema::write(r),
35        }
36    }
37    fn from_stored(stored: Value) -> Option<Self> {
38        match stored {
39            Value::Ref(r) => Image::of_ref(&r),
40            Value::Str(s) => match classify(&s).ok()? {
41                Spelled::Ref(r) => Image::of_ref(&r),
42                Spelled::Plain(_) | Spelled::Bytes(_) => None,
43            },
44            _ => None,
45        }
46    }
47}
48
49substrate_data::named_schema!(Image);