mirror of
https://github.com/danbulant/icon
synced 2026-07-06 11:30:35 +00:00
Rename ThemeDescriptor → ThemeInfo
This commit is contained in:
parent
1edb93e47c
commit
bf539834f8
3 changed files with 37 additions and 39 deletions
|
|
@ -5,7 +5,7 @@
|
||||||
//! # Quick start
|
//! # Quick start
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! let dirs = icon::IconSearch::default();
|
//! let icons = icon::Icons::new();
|
||||||
//! // TODO.
|
//! // TODO.
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
//!
|
//!
|
||||||
//! To find icons in a theme, its `index.theme` file must be parsed to understand the directory
|
//! To find icons in a theme, its `index.theme` file must be parsed to understand the directory
|
||||||
//! structure within the theme itself.
|
//! structure within the theme itself.
|
||||||
//! This is handled by [ThemeDescriptor].
|
//! This is handled by [theme::ThemeInfo].
|
||||||
//!
|
//!
|
||||||
//! 3a. *Find just one icon* (oneshot):
|
//! 3a. *Find just one icon* (oneshot):
|
||||||
//!
|
//!
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
use crate::icon::IconFile;
|
use crate::icon::IconFile;
|
||||||
use crate::theme::{Icons, Theme, ThemeInfo, ThemeParseError};
|
use crate::theme::{Icons, Theme, ThemeInfo, ThemeParseError};
|
||||||
|
use states::*;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ffi::{OsStr, OsString};
|
use std::ffi::{OsStr, OsString};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use states::*;
|
|
||||||
|
|
||||||
macro_rules! states {
|
macro_rules! states {
|
||||||
($($(#[$($attr:tt)*])* $id:ident),*) => {
|
($($(#[$($attr:tt)*])* $id:ident),*) => {
|
||||||
|
|
@ -216,7 +216,7 @@ impl IconSearch<LocationsFound> {
|
||||||
dirs: self.dirs,
|
dirs: self.dirs,
|
||||||
icon_locations: None, // consumed!
|
icon_locations: None, // consumed!
|
||||||
icons: Some(icons),
|
icons: Some(icons),
|
||||||
_state: PhantomData
|
_state: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -296,7 +296,7 @@ impl IconLocations {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let descriptor = match locations.load_single_theme(name) {
|
let info = match locations.load_single_theme(name) {
|
||||||
Ok(d) => Some(d),
|
Ok(d) => Some(d),
|
||||||
Err(_e) => {
|
Err(_e) => {
|
||||||
#[cfg(feature = "log")]
|
#[cfg(feature = "log")]
|
||||||
|
|
@ -305,13 +305,13 @@ impl IconLocations {
|
||||||
None
|
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;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let parents = descriptor.index.inherits.clone();
|
let parents = info.index.inherits.clone();
|
||||||
|
|
||||||
// Collect all parents of this theme:
|
// Collect all parents of this theme:
|
||||||
for parent in parents {
|
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();
|
let mut themes = HashMap::new();
|
||||||
|
|
||||||
// collect all required themes:
|
// collect all required themes:
|
||||||
|
|
@ -334,18 +334,18 @@ impl IconLocations {
|
||||||
// of course, the user might be cursed and not have `hicolor` installed at all!
|
// 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.
|
// 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)
|
// were invalid)
|
||||||
// we'll also split them up, as `theme_chains` borrows names from `theme_names`,
|
// 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
|
// but we need to mutate theme_info later (during the borrow) to avoid
|
||||||
// cloning the descriptions
|
// cloning the info
|
||||||
let (theme_names, mut theme_descriptions): (Vec<_>, Vec<_>) = themes
|
let (theme_names, mut theme_info): (Vec<_>, Vec<_>) = themes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|(key, value)| value.map(|v| (key, Some(v))))
|
.flat_map(|(key, value)| value.map(|v| (key, Some(v))))
|
||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
// the Options are there just so we can take descriptions out of the vec without messing up the order.
|
// the Options are there just so we can take info out of the vec without messing up the order.
|
||||||
debug_assert!(theme_descriptions.iter().all(Option::is_some));
|
debug_assert!(theme_info.iter().all(Option::is_some));
|
||||||
|
|
||||||
// do we even have hicolor?
|
// do we even have hicolor?
|
||||||
// if not, there's no use in inserting hicolor into the inheritance tree later
|
// 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.
|
// 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.
|
// 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 number_of_themes = theme_names.len();
|
||||||
let mut theme_chains = Vec::<Vec<usize>>::with_capacity(number_of_themes);
|
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() {
|
while let Some(node_idx) = chain.get(cursor).copied() {
|
||||||
cursor += 1;
|
cursor += 1;
|
||||||
|
|
||||||
let Some(Some(description)) = theme_descriptions.get(node_idx) else {
|
let Some(Some(info)) = theme_info.get(node_idx) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
for parent in &description.index.inherits {
|
for parent in &info.index.inherits {
|
||||||
let Some(parent_idx) = theme_names
|
let Some(parent_idx) = theme_names
|
||||||
.iter()
|
.iter()
|
||||||
.position(|name| *name.as_os_str() == **parent)
|
.position(|name| *name.as_os_str() == **parent)
|
||||||
|
|
@ -410,9 +410,9 @@ impl IconLocations {
|
||||||
for chain in &theme_chains {
|
for chain in &theme_chains {
|
||||||
// go from last theme to first, as all dependencies are "forward" in the chain:
|
// go from last theme to first, as all dependencies are "forward" in the chain:
|
||||||
for theme_idx in chain.iter().copied().rev() {
|
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 :-)
|
// the option was None, meaning this theme was processed already :-)
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
@ -428,7 +428,7 @@ impl IconLocations {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let theme = Theme {
|
let theme = Theme {
|
||||||
description: theme_desc,
|
info: theme_info,
|
||||||
inherits_from: parents,
|
inherits_from: parents,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -531,7 +531,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_standard_usage() {
|
fn test_standard_usage() {
|
||||||
let icons = IconSearch::default()
|
let _icons = IconSearch::default()
|
||||||
.add_directories(["/this/path/probably/doesnt/exist/but/who/cares/"])
|
.add_directories(["/this/path/probably/doesnt/exist/but/who/cares/"])
|
||||||
.search()
|
.search()
|
||||||
.icons();
|
.icons();
|
||||||
|
|
@ -543,8 +543,8 @@ mod test {
|
||||||
|
|
||||||
let locations = dirs.find_icon_locations();
|
let locations = dirs.find_icon_locations();
|
||||||
|
|
||||||
let descriptor = locations.load_single_theme("Adwaita").unwrap();
|
let info = locations.load_single_theme("Adwaita").unwrap();
|
||||||
assert_eq!(descriptor.index.name, "Adwaita");
|
assert_eq!(info.index.name, "Adwaita");
|
||||||
|
|
||||||
let icon = locations.standalone_icon("htop").unwrap();
|
let icon = locations.standalone_icon("htop").unwrap();
|
||||||
assert_eq!(icon.path.file_name(), Some("htop.png".as_ref()))
|
assert_eq!(icon.path.file_name(), Some("htop.png".as_ref()))
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::IconSearch;
|
||||||
use crate::icon::IconFile;
|
use crate::icon::IconFile;
|
||||||
use crate::theme::ThemeParseError::MissingRequiredAttribute;
|
use crate::theme::ThemeParseError::MissingRequiredAttribute;
|
||||||
use freedesktop_entry_parser::low_level::{EntryIter, SectionBytes};
|
use freedesktop_entry_parser::low_level::{EntryIter, SectionBytes};
|
||||||
|
|
@ -5,7 +6,6 @@ use std::collections::HashMap;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use crate::IconSearch;
|
|
||||||
|
|
||||||
pub struct Icons {
|
pub struct Icons {
|
||||||
pub standalone_icons: Vec<IconFile>,
|
pub standalone_icons: Vec<IconFile>,
|
||||||
|
|
@ -18,14 +18,12 @@ impl Icons {
|
||||||
/// This function collects all standalone icons and icon themes on the system.
|
/// This function collects all standalone icons and icon themes on the system.
|
||||||
/// To configure what directories are searched, use [`IconSearch`] instead.
|
/// To configure what directories are searched, use [`IconSearch`] instead.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
IconSearch::default()
|
IconSearch::default().search().icons()
|
||||||
.search()
|
|
||||||
.icons()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Theme {
|
pub struct Theme {
|
||||||
pub description: ThemeInfo,
|
pub info: ThemeInfo,
|
||||||
pub inherits_from: Vec<Arc<Theme>>,
|
pub inherits_from: Vec<Arc<Theme>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue