use std::borrow::Cow;
use std::sync::Arc;
use gpui::{AssetSource, Result, SharedString};
use rust_embed::RustEmbed;
use serde::{Deserialize, Serialize};
use strum::{EnumIter, EnumString, IntoStaticStr};
#[derive(
Debug, PartialEq, Eq, Copy, Clone, EnumIter, EnumString, IntoStaticStr, Serialize, Deserialize,
)]
#[strum(serialize_all = "snake_case")]
pub enum IconName {
AcpRegistry,
AiAnthropic,
AiBedrock,
AiClaude,
AiDeepSeek,
AiEdit,
AiGemini,
AiGoogle,
AiLmStudio,
AiMistral,
AiOllama,
AiOpenAi,
AiOpenAiCompat,
AiOpenCode,
AiOpenRouter,
AiVercel,
AiXAi,
Archive,
ArrowCircle,
ArrowDown,
ArrowDown10,
ArrowDownRight,
ArrowLeft,
ArrowRight,
ArrowRightLeft,
ArrowUp,
ArrowUpRight,
AtSign,
Attach,
AudioOff,
AudioOn,
Backspace,
Bell,
BellDot,
BellOff,
BellRing,
Binary,
Blocks,
Bookmark,
BoltFilled,
BoltOutlined,
Book,
BookCopy,
Box,
BoxOpen,
CaseSensitive,
Chat,
Check,
CheckCircle,
CheckDouble,
ChevronDown,
ChevronDownUp,
ChevronLeft,
ChevronRight,
ChevronUp,
ChevronUpDown,
Circle,
CircleHelp,
Clock,
Close,
CloudDownload,
Code,
Command,
Control,
Copilot,
CopilotDisabled,
CopilotError,
CopilotInit,
Copy,
CountdownTimer,
Crosshair,
CursorIBeam,
Dash,
DatabaseZap,
Debug,
DebugBreakpoint,
DebugContinue,
DebugDetach,
DebugDisabledBreakpoint,
DebugDisabledLogBreakpoint,
DebugIgnoreBreakpoints,
DebugLogBreakpoint,
DebugPause,
DebugStepInto,
DebugStepOut,
DebugStepOver,
Diff,
DiffSplit,
DiffSplitAuto,
DiffUnified,
Disconnected,
Download,
EditorAtom,
EditorCursor,
EditorEmacs,
EditorJetBrains,
EditorSublime,
EditorVsCode,
Ellipsis,
Envelope,
Eraser,
Escape,
Exit,
ExpandDown,
ExpandUp,
ExpandVertical,
Eye,
EyeOff,
FastForward,
FastForwardOff,
File,
FileCode,
FileDiff,
FileDoc,
FileGeneric,
FileGit,
FileLock,
FileMarkdown,
FileRust,
FileTextFilled,
FileTextOutlined,
FileToml,
FileTree,
Filter,
Flame,
Folder,
FolderOpen,
FolderOpenAdd,
FolderSearch,
Font,
FontSize,
FontWeight,
ForwardArrow,
ForwardArrowUp,
GenericClose,
GenericMaximize,
GenericMinimize,
GenericRestore,
GitBranch,
GitBranchPlus,
GitCommit,
GitGraph,
GitMergeConflict,
GitWorktree,
Github,
Hash,
HistoryRerun,
Image,
Inception,
Indicator,
Info,
Json,
Keyboard,
Library,
LineHeight,
Link,
Linux,
ListCollapse,
ListFilter,
ListTodo,
ListTree,
ListX,
LoadCircle,
LocationEdit,
LockOutlined,
MagnifyingGlass,
Maximize,
MaximizeAlt,
Menu,
MenuAltTemp,
Mic,
MicMute,
Minimize,
NewThread,
Notepad,
OpenFolder,
Option,
PageDown,
PageUp,
Paperclip,
Pencil,
PencilUnavailable,
Person,
Pin,
PlayFilled,
PlayOutlined,
Plus,
Power,
Public,
PullRequest,
QueueMessage,
Quote,
Reader,
RefreshTitle,
Regex,
ReplNeutral,
Replace,
ReplaceAll,
ReplaceNext,
ReplyArrowRight,
Rerun,
Return,
RotateCcw,
RotateCw,
Scissors,
Screen,
SelectAll,
Send,
Server,
Settings,
Shift,
SignalHigh,
SignalLow,
SignalMedium,
Slash,
Sliders,
Space,
Sparkle,
Split,
SplitAlt,
SquareDot,
SquareMinus,
SquarePlus,
Star,
StarFilled,
Stop,
Tab,
Terminal,
TerminalAlt,
TextSnippet,
ThinkingMode,
ThinkingModeOff,
Thread,
ThreadFromSummary,
ThreadsSidebarLeftClosed,
ThreadsSidebarLeftOpen,
ThreadsSidebarRightClosed,
ThreadsSidebarRightOpen,
ThumbsDown,
ThumbsUp,
TodoComplete,
TodoPending,
TodoProgress,
ToolCopy,
ToolDeleteFile,
ToolDiagnostics,
ToolFolder,
ToolHammer,
ToolNotification,
ToolPencil,
ToolSearch,
ToolTerminal,
ToolThink,
ToolWeb,
Trash,
Triangle,
TriangleRight,
Undo,
Unpin,
User,
UserCheck,
UserGroup,
UserRoundPen,
Warning,
WholeWord,
ExclamationTriangle,
XCircle,
XCircleFilled,
XMark,
}
impl IconName {
pub fn path(&self) -> Arc<str> {
let file_stem: &'static str = self.into();
format!("icons/{file_stem}.svg").into()
}
}
#[derive(RustEmbed)]
#[folder = "assets"]
#[include = "icons/**/*.svg"]
#[include = "fonts/**/*.ttf"]
pub struct Assets;
impl AssetSource for Assets {
fn load(&self, path: &str) -> Result<Option<Cow<'static, [u8]>>> {
Ok(Self::get(path).map(|f| f.data))
}
fn list(&self, path: &str) -> Result<Vec<SharedString>> {
Ok(Self::iter()
.filter(|p| p.starts_with(path))
.map(|p| SharedString::from(p.to_string()))
.collect())
}
}
#[cfg(test)]
mod tests {
use super::*;
const REFERENCED: &[IconName] = &[
IconName::AcpRegistry,
IconName::AiClaude,
IconName::AiEdit,
IconName::AiOpenAi,
IconName::AiOpenCode,
IconName::Archive,
IconName::ArrowCircle,
IconName::ArrowDown,
IconName::ArrowLeft,
IconName::ArrowRight,
IconName::ArrowUp,
IconName::ArrowUpRight,
IconName::AtSign,
IconName::AudioOff,
IconName::Backspace,
IconName::Bell,
IconName::Blocks,
IconName::BoltFilled,
IconName::Box,
IconName::Check,
IconName::CheckCircle,
IconName::ChevronDown,
IconName::ChevronLeft,
IconName::ChevronRight,
IconName::ChevronUp,
IconName::ChevronUpDown,
IconName::Circle,
IconName::Clock,
IconName::Close,
IconName::Command,
IconName::Control,
IconName::Copy,
IconName::CountdownTimer,
IconName::Dash,
IconName::Download,
IconName::Ellipsis,
IconName::Escape,
IconName::ExclamationTriangle,
IconName::File,
IconName::FileDoc,
IconName::FileRust,
IconName::Folder,
IconName::FolderOpen,
IconName::GitBranch,
IconName::GitWorktree,
IconName::Info,
IconName::ListTree,
IconName::LoadCircle,
IconName::MagnifyingGlass,
IconName::MicMute,
IconName::Option,
IconName::PageDown,
IconName::PageUp,
IconName::Paperclip,
IconName::Person,
IconName::PlayFilled,
IconName::Plus,
IconName::Return,
IconName::RotateCw,
IconName::Settings,
IconName::Shift,
IconName::Space,
IconName::Sparkle,
IconName::Split,
IconName::Star,
IconName::Tab,
IconName::ToolHammer,
IconName::ToolTerminal,
IconName::ToolThink,
IconName::Trash,
IconName::Triangle,
IconName::Undo,
IconName::User,
IconName::Warning,
IconName::XCircle,
IconName::XMark,
];
#[test]
fn referenced_icons_have_assets() {
for icon in REFERENCED {
let path = icon.path();
assert!(
Assets::get(&path).is_some(),
"IconName::{:?} -> {} has no embedded SVG asset",
icon,
path
);
}
}
}