snora_core/icon.rs
1//! Icon vocabulary.
2//!
3//! snora supports icons from multiple sources. Each source is gated behind
4//! a Cargo feature so that unused icon backends are eliminated at compile
5//! time (DCE) — no bundled asset blob you aren't using.
6//!
7//! | Source | Feature flag | Variant |
8//! |--------|--------------|---------|
9//! | Plain text (glyph / emoji) | always available | [`Icon::Text`] |
10//! | Lucide icon set | `lucide-icons` | [`Icon::Lucide`] |
11//! | Custom SVG file | `svg-icons` | [`Icon::Svg`] |
12//!
13//! When a feature is disabled, its variant does not exist in the enum at
14//! all — the compiler will refuse code that references it, so there are no
15//! runtime "unimplemented!" paths.
16//!
17//! # Fallback ergonomics
18//!
19//! `Icon` accepts `&str` / `String` conversions directly so that icon fields
20//! in user code can degrade gracefully even with all features disabled:
21//!
22//! ```rust
23//! # use snora_core::Icon;
24//! let icon: Icon = "★".into(); // always works
25//! let icon: Icon = String::from("★").into();
26//! ```
27
28#[derive(Debug, Clone)]
29pub enum Icon {
30 /// Renders the given string as text. The engine may choose its font
31 /// and size; a single-glyph string acts as a tiny glyph icon.
32 Text(String),
33
34 /// A built-in Lucide icon. Requires the `lucide-icons` feature.
35 #[cfg(feature = "lucide-icons")]
36 Lucide(lucide_icons::Icon),
37
38 /// A custom SVG file loaded from disk. Requires the `svg-icons`
39 /// feature. The engine is responsible for reading and rasterizing
40 /// the file.
41 #[cfg(feature = "svg-icons")]
42 Svg(std::path::PathBuf),
43}
44
45impl From<&str> for Icon {
46 fn from(s: &str) -> Self {
47 Icon::Text(s.to_string())
48 }
49}
50
51impl From<String> for Icon {
52 fn from(s: String) -> Self {
53 Icon::Text(s)
54 }
55}
56
57#[cfg(feature = "lucide-icons")]
58impl From<lucide_icons::Icon> for Icon {
59 fn from(i: lucide_icons::Icon) -> Self {
60 Icon::Lucide(i)
61 }
62}