use anyhow::Result;
use gpui::{AssetSource, SharedString};
use rust_embed::RustEmbed;
use std::borrow::Cow;
pub trait Resource: RustEmbed {
fn by_path(path: &str) -> Option<Cow<'static, [u8]>> {
Self::get(path).map(|file| file.data)
}
fn has(path: &str) -> bool {
Self::get(path).is_some()
}
fn list(prefix: Option<&str>) -> Vec<String> {
match prefix {
Some(prefix) => Self::iter()
.filter(|path| path.starts_with(prefix))
.map(|s| s.to_string())
.collect(),
None => Self::iter().map(|s| s.to_string()).collect(),
}
}
}
impl<T: RustEmbed> Resource for T {}
pub struct ResourceSource<T: Resource + Send + Sync> {
_phantom: std::marker::PhantomData<T>,
}
impl<T: Resource + Send + Sync> Default for ResourceSource<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: Resource + Send + Sync> ResourceSource<T> {
pub fn new() -> Self {
Self {
_phantom: std::marker::PhantomData,
}
}
}
impl<T: Resource + Send + Sync + 'static> AssetSource for ResourceSource<T> {
fn load(&self, path: &str) -> Result<Option<Cow<'static, [u8]>>> {
Ok(T::by_path(path))
}
fn list(&self, prefix: &str) -> Result<Vec<SharedString>> {
Ok(T::list(Some(prefix))
.into_iter()
.map(|s| s.into())
.collect())
}
}