cobble_core/minecraft/shaderpacks/
mod.rs

1mod shaderpack;
2
3use crate::error::{CobbleError, CobbleResult};
4use futures::TryStreamExt;
5pub use shaderpack::*;
6use std::path::{Path, PathBuf};
7use tokio::fs::read_dir;
8use tokio_stream::wrappers::ReadDirStream;
9
10/// Loads all shaderpacks from the minecraft folder.
11#[cfg_attr(doc_cfg, doc(cfg(feature = "shaderpacks")))]
12#[instrument(
13    name = "load_shaderpacks",
14    level = "debug",
15    skip_all,
16    fields(minecraft_path)
17)]
18pub async fn load_shaderpacks(minecraft_path: impl AsRef<Path>) -> CobbleResult<Vec<Shaderpack>> {
19    let mut shaderpacks_path = PathBuf::from(minecraft_path.as_ref());
20    shaderpacks_path.push("shaderpacks");
21
22    if !shaderpacks_path.is_dir() {
23        trace!("Shaderpacks directory is empty");
24        return Ok(vec![]);
25    }
26
27    trace!("Loading loader mod files...");
28    let file_stream = ReadDirStream::new(read_dir(shaderpacks_path).await?);
29    let shaderpacks = file_stream
30        .map_err(CobbleError::from)
31        .try_filter_map(|e| parse_shaderpack(e.path()))
32        .try_collect()
33        .await?;
34
35    Ok(shaderpacks)
36}
37
38#[instrument(name = "parse_shaderpack", level = "trace", skip_all, fields(path,))]
39pub(crate) async fn parse_shaderpack(path: impl AsRef<Path>) -> CobbleResult<Option<Shaderpack>> {
40    // Check if file
41    if !path.as_ref().is_file() {
42        trace!("Entry is not a file.");
43        return Ok(None);
44    }
45
46    // Check if archive
47    let mime = match mime_guess::from_path(&path).first() {
48        Some(mime) => mime,
49        None => {
50            trace!("Could not get MIME type for file.");
51            return Ok(None);
52        }
53    };
54    if mime != "application/zip" {
55        trace!("Entry is not an archive");
56        return Ok(None);
57    }
58
59    // Parse
60    let name = match path.as_ref().file_name() {
61        Some(name) => name.to_string_lossy().to_string(),
62        None => return Ok(None),
63    };
64
65    Ok(Some(Shaderpack {
66        name,
67        path: PathBuf::from(path.as_ref()),
68    }))
69}