Rename ThemeDescriptorThemeInfo

This commit is contained in:
Ridan Vandenbergh 2025-06-20 22:24:41 +02:00
parent 1edb93e47c
commit bf539834f8
No known key found for this signature in database
3 changed files with 37 additions and 39 deletions

View file

@ -5,7 +5,7 @@
//! # Quick start
//!
//! ```
//! let dirs = icon::IconSearch::default();
//! let icons = icon::Icons::new();
//! // TODO.
//! ```
//!
@ -34,7 +34,7 @@
//!
//! To find icons in a theme, its `index.theme` file must be parsed to understand the directory
//! structure within the theme itself.
//! This is handled by [ThemeDescriptor].
//! This is handled by [theme::ThemeInfo].
//!
//! 3a. *Find just one icon* (oneshot):
//!

View file

@ -1,11 +1,11 @@
use crate::icon::IconFile;
use crate::theme::{Icons, Theme, ThemeInfo, ThemeParseError};
use states::*;
use std::collections::HashMap;
use std::ffi::{OsStr, OsString};
use std::marker::PhantomData;
use std::path::PathBuf;
use std::sync::Arc;
use states::*;
macro_rules! states {
($($(#[$($attr:tt)*])* $id:ident),*) => {
@ -90,7 +90,7 @@ impl IconSearch<Initial> {
/// - `$HOME/.icons`
/// - `$XDG_DATA_DIRS/icons`
/// - `/usr/share/pixmaps`
///
///
/// If you wish to add directories to those, use this function and then [`add_directories`](Self::add_directories).
pub fn default() -> Self {
<Self as Default>::default()
@ -174,7 +174,7 @@ impl IconSearch<Initial> {
themes_directories,
}
}
/// Find icons and icon themes in the configured search directories.
///
/// This function proceeds the [`IconSearch`] to the [next stage](LocationsFound).
@ -197,9 +197,9 @@ impl IconSearch<LocationsFound> {
.as_ref()
.expect("guaranteed by type-state")
}
/// Consume this `IconSearch` to expose its [`IconLocations`].
///
///
/// Contained search directories are lost.
pub fn into_icon_locations(self) -> IconLocations {
let icons = self.icon_locations.expect("guaranteed by type-state");
@ -207,7 +207,7 @@ impl IconSearch<LocationsFound> {
}
// -- STAGE 3: We have icon theme candidates, so it's time to resolve them.
fn finish(self) -> IconSearch<Finished> {
let icons = self.icon_locations.expect("guaranteed by type-state");
let icons = icons.icons();
@ -216,7 +216,7 @@ impl IconSearch<LocationsFound> {
dirs: self.dirs,
icon_locations: None, // consumed!
icons: Some(icons),
_state: PhantomData
_state: PhantomData,
}
}
@ -251,7 +251,7 @@ impl IconLocations {
/// use icon::IconSearch;
/// let search = IconSearch::default()
/// .search();
///
///
/// let locations = search.into_icon_locations();
/// ```
pub fn from_icon_search(dirs: &IconSearch<Initial>) -> Self {
@ -296,7 +296,7 @@ impl IconLocations {
return;
}
let descriptor = match locations.load_single_theme(name) {
let info = match locations.load_single_theme(name) {
Ok(d) => Some(d),
Err(_e) => {
#[cfg(feature = "log")]
@ -305,13 +305,13 @@ impl IconLocations {
None
}
};
let descriptor = themes.entry(name.to_os_string()).insert_entry(descriptor);
let info = themes.entry(name.to_os_string()).insert_entry(info);
let Some(descriptor) = descriptor.get() else {
let Some(info) = info.get() else {
return;
};
let parents = descriptor.index.inherits.clone();
let parents = info.index.inherits.clone();
// Collect all parents of this theme:
for parent in parents {
@ -319,7 +319,7 @@ impl IconLocations {
}
}
// Map from theme names to their descriptor:
// Map from theme names to their info:
let mut themes = HashMap::new();
// collect all required themes:
@ -334,18 +334,18 @@ impl IconLocations {
// of course, the user might be cursed and not have `hicolor` installed at all!
// that is troubling, but we'll see that it is handled correctly below.
// let's prune theme candidates that have no description (meaning they weren't themes, or
// let's prune theme candidates that have no info (meaning they weren't themes, or
// were invalid)
// we'll also split them up, as `theme_chains` borrows names from `theme_names`,
// but we need to mutate theme_descriptions later (during the borrow) to avoid
// cloning the descriptions
let (theme_names, mut theme_descriptions): (Vec<_>, Vec<_>) = themes
// but we need to mutate theme_info later (during the borrow) to avoid
// cloning the info
let (theme_names, mut theme_info): (Vec<_>, Vec<_>) = themes
.into_iter()
.flat_map(|(key, value)| value.map(|v| (key, Some(v))))
.unzip();
// the Options are there just so we can take descriptions out of the vec without messing up the order.
debug_assert!(theme_descriptions.iter().all(Option::is_some));
// the Options are there just so we can take info out of the vec without messing up the order.
debug_assert!(theme_info.iter().all(Option::is_some));
// do we even have hicolor?
// if not, there's no use in inserting hicolor into the inheritance tree later
@ -356,7 +356,7 @@ impl IconLocations {
// DFS would de facto end up in hicolor before ever trying the second theme in an Inherits set.
// Therefore, BFS is the only sensible option, but the spec doesn't define this.
// indexed by the position in our theme_names/theme_descriptions vecs
// indexed by the position in our theme_names/theme_info vecs
let number_of_themes = theme_names.len();
let mut theme_chains = Vec::<Vec<usize>>::with_capacity(number_of_themes);
@ -367,11 +367,11 @@ impl IconLocations {
while let Some(node_idx) = chain.get(cursor).copied() {
cursor += 1;
let Some(Some(description)) = theme_descriptions.get(node_idx) else {
let Some(Some(info)) = theme_info.get(node_idx) else {
continue;
};
for parent in &description.index.inherits {
for parent in &info.index.inherits {
let Some(parent_idx) = theme_names
.iter()
.position(|name| *name.as_os_str() == **parent)
@ -410,9 +410,9 @@ impl IconLocations {
for chain in &theme_chains {
// go from last theme to first, as all dependencies are "forward" in the chain:
for theme_idx in chain.iter().copied().rev() {
let theme_desc = theme_descriptions[theme_idx].take();
let theme_info = theme_info[theme_idx].take();
let Some(theme_desc) = theme_desc else {
let Some(theme_info) = theme_info else {
// the option was None, meaning this theme was processed already :-)
continue;
};
@ -428,7 +428,7 @@ impl IconLocations {
.collect();
let theme = Theme {
description: theme_desc,
info: theme_info,
inherits_from: parents,
};
@ -454,10 +454,10 @@ impl IconLocations {
}
/// Parse a single theme, returning its info.
///
///
/// This is a rather low-level function, as it does not give you (easy) access to a usable
/// version of the theme's inheritance tree.
///
///
/// Unless theme metadata is all you need, use [`resolve`](IconLocations::resolve) or [`resolve_only`](IconLocations::resolve_only) instead!
pub fn load_single_theme<S>(&self, internal_name: S) -> std::io::Result<ThemeInfo>
where
@ -531,20 +531,20 @@ mod test {
#[test]
fn test_standard_usage() {
let icons = IconSearch::default()
let _icons = IconSearch::default()
.add_directories(["/this/path/probably/doesnt/exist/but/who/cares/"])
.search()
.icons();
}
#[test]
fn test_find_standard_theme_and_icon() {
let dirs = IconSearch::default();
let locations = dirs.find_icon_locations();
let descriptor = locations.load_single_theme("Adwaita").unwrap();
assert_eq!(descriptor.index.name, "Adwaita");
let info = locations.load_single_theme("Adwaita").unwrap();
assert_eq!(info.index.name, "Adwaita");
let icon = locations.standalone_icon("htop").unwrap();
assert_eq!(icon.path.file_name(), Some("htop.png".as_ref()))

View file

@ -1,3 +1,4 @@
use crate::IconSearch;
use crate::icon::IconFile;
use crate::theme::ThemeParseError::MissingRequiredAttribute;
use freedesktop_entry_parser::low_level::{EntryIter, SectionBytes};
@ -5,7 +6,6 @@ use std::collections::HashMap;
use std::ffi::OsString;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use crate::IconSearch;
pub struct Icons {
pub standalone_icons: Vec<IconFile>,
@ -14,18 +14,16 @@ pub struct Icons {
impl Icons {
/// Creates a new `Icons`, performing a search in the standard directories.
///
///
/// This function collects all standalone icons and icon themes on the system.
/// To configure what directories are searched, use [`IconSearch`] instead.
pub fn new() -> Self {
IconSearch::default()
.search()
.icons()
IconSearch::default().search().icons()
}
}
pub struct Theme {
pub description: ThemeInfo,
pub info: ThemeInfo,
pub inherits_from: Vec<Arc<Theme>>,
}