fix(assets,theme): remove assert in svg_loader, log theme failures, fix default theme id (#58, #63, #64)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
funman300
2026-05-27 19:36:05 -07:00
parent 35fde160fa
commit 0437c36463
3 changed files with 38 additions and 14 deletions
+26 -5
View File
@@ -21,11 +21,12 @@
use std::path::Path;
use bevy::log::warn;
use bevy::prelude::{App, Plugin, Resource, Startup};
use serde::Deserialize;
use super::ThemeMeta;
use crate::assets::{user_theme_dir, DARK_THEME_MANIFEST_URL};
use crate::assets::{DARK_THEME_MANIFEST_URL, user_theme_dir};
/// One entry in the [`ThemeRegistry`] — the data the picker UI needs
/// to render a row and load the theme on selection.
@@ -143,7 +144,7 @@ fn classic_entry() -> ThemeEntry {
/// Walks `user_dir`, treating every immediate subdirectory as a
/// candidate theme. A subdirectory contributes one entry if and only
/// if it contains a `theme.ron` whose `meta` block parses cleanly and
/// passes `ThemeMeta::validate`. Failed candidates are silently
/// passes `ThemeMeta::validate`. Failed candidates are warned and
/// skipped — broken themes don't poison discovery.
fn discover_user_themes(user_dir: &Path) -> Vec<ThemeEntry> {
let mut out = Vec::new();
@@ -184,9 +185,29 @@ struct ManifestMetaOnly {
/// [`ThemeEntry`]. Returns `None` for any I/O / parse / validation
/// failure — discovery is best-effort.
fn read_meta_only(manifest_path: &Path) -> Option<ThemeEntry> {
let bytes = std::fs::read(manifest_path).ok()?;
let parsed: ManifestMetaOnly = ron::de::from_bytes(&bytes).ok()?;
parsed.meta.validate().ok()?;
let theme_id = manifest_path
.parent()
.and_then(Path::file_name)
.and_then(|name| name.to_str())
.unwrap_or("<unknown>");
let bytes = match std::fs::read(manifest_path) {
Ok(bytes) => bytes,
Err(e) => {
warn!("Skipping theme '{}': {}", theme_id, e);
return None;
}
};
let parsed: ManifestMetaOnly = match ron::de::from_bytes(&bytes) {
Ok(parsed) => parsed,
Err(e) => {
warn!("Skipping theme '{}': {}", theme_id, e);
return None;
}
};
if let Err(e) = parsed.meta.validate() {
warn!("Skipping theme '{}': {}", theme_id, e);
return None;
}
let id = parsed.meta.id.clone();
let display_name = parsed.meta.name.clone();
let manifest_url = format!("themes://{id}/theme.ron");