native-theme-build
Build-time code generation for native-theme custom icon roles.
This crate reads TOML icon definitions at build time and generates a Rust enum
that implements native_theme::IconProvider. The generated enum maps each icon
role to platform-specific identifiers (SF Symbols, Segoe Fluent, freedesktop,
Material, Lucide) and optionally embeds bundled SVG data via include_bytes!.
Quick Start
Add the build dependency:
[]
= "0.5.3"
Create an icon definition TOML:
# icons/icons.toml
= "app-icon"
= ["play-pause", "skip-forward", "volume-up"]
= ["material"]
= ["sf-symbols", "segoe-fluent", "freedesktop"]
Call generate_icons() in your build.rs:
use UnwrapOrExit;
Include and use the generated code:
include!;
use ;
let icon_data = load_custom_icon;
TOML Schema
The master TOML file declares the icon set name, roles, and which themes to support:
name-- used to derive the generated enum name (AppIcon).roles-- kebab-case role names; each becomes a PascalCase enum variant.bundled-themes-- themes whose SVGs are embedded viainclude_bytes!.system-themes-- themes resolved at runtime by the OS (no embedded SVGs).
Directory Layout
icons/
icons.toml # Master TOML (the file passed to generate_icons)
material/
mapping.toml # Role -> SVG filename mappings
play_pause.svg
skip_next.svg
volume_up.svg
sf-symbols/
mapping.toml # Role -> SF Symbol name mappings
segoe-fluent/
mapping.toml # Role -> Segoe codepoint mappings
freedesktop/
mapping.toml # Role -> freedesktop icon name mappings
Mapping Format
Each theme directory contains a mapping.toml that maps roles to
theme-specific identifiers. Simple form:
= "play_pause"
= "skip_next"
= "volume_up"
DE-aware form (for freedesktop themes that vary by desktop environment):
= { = "media-playback-start", = "media-play" }
A default key is required for every DE-aware entry.
Builder API
For projects with multiple TOML files or custom enum names:
use UnwrapOrExit;
Both APIs resolve paths relative to CARGO_MANIFEST_DIR, emit
cargo::rerun-if-changed directives for all referenced files, and write
the generated code to OUT_DIR.
What Gets Generated
The output is a single .rs file containing:
- A
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]enum with one variant per role. - An
IconProviderimplementation withicon_name()returning the platform-specific identifier andicon_svg()returninginclude_bytes!(...)data for bundled themes.
Validation
Build errors are emitted at compile time for:
- Missing roles in mapping files (every role must be present in every theme).
- Missing SVG files for bundled themes.
- Unknown role names in mapping files (not declared in the master TOML).
- Duplicate roles across multiple TOML files (builder API).
- Missing
defaultkey in DE-aware mapping entries.
License
Licensed under either of
at your option.