egui/load/
bytes_loader.rs

1use super::{
2    generate_loader_id, Bytes, BytesLoadResult, BytesLoader, BytesPoll, Context, Cow, HashMap,
3    LoadError, Mutex,
4};
5
6/// Maps URI:s to [`Bytes`], e.g. found with `include_bytes!`.
7///
8/// By convention, the URI:s should be prefixed with `bytes://`.
9#[derive(Default)]
10pub struct DefaultBytesLoader {
11    cache: Mutex<HashMap<Cow<'static, str>, Bytes>>,
12}
13
14impl DefaultBytesLoader {
15    pub fn insert(&self, uri: impl Into<Cow<'static, str>>, bytes: impl Into<Bytes>) {
16        self.cache
17            .lock()
18            .entry(uri.into())
19            .or_insert_with_key(|_uri| {
20                let bytes: Bytes = bytes.into();
21
22                #[cfg(feature = "log")]
23                log::trace!("loaded {} bytes for uri {_uri:?}", bytes.len());
24
25                bytes
26            });
27    }
28}
29
30impl BytesLoader for DefaultBytesLoader {
31    fn id(&self) -> &str {
32        generate_loader_id!(DefaultBytesLoader)
33    }
34
35    fn load(&self, _: &Context, uri: &str) -> BytesLoadResult {
36        // We accept uri:s that don't start with `bytes://` too… for now.
37        match self.cache.lock().get(uri).cloned() {
38            Some(bytes) => Ok(BytesPoll::Ready {
39                size: None,
40                bytes,
41                mime: None,
42            }),
43            None => {
44                if uri.starts_with("bytes://") {
45                    Err(LoadError::Loading(
46                        "Bytes not found. Did you forget to call Context::include_bytes?".into(),
47                    ))
48                } else {
49                    Err(LoadError::NotSupported)
50                }
51            }
52        }
53    }
54
55    fn forget(&self, uri: &str) {
56        #[cfg(feature = "log")]
57        log::trace!("forget {uri:?}");
58
59        self.cache.lock().remove(uri);
60    }
61
62    fn forget_all(&self) {
63        #[cfg(feature = "log")]
64        log::trace!("forget all");
65
66        self.cache.lock().clear();
67    }
68
69    fn byte_size(&self) -> usize {
70        self.cache.lock().values().map(|bytes| bytes.len()).sum()
71    }
72}