file_browser/
file_browser.rs

1//! File browser example
2//!
3//! This example demonstrates how to use unicode-rs to create a file browser
4//! with file type indicators, similar to what you might see in a terminal file manager.
5
6use unicode_rs::prelude::*;
7
8#[derive(Debug)]
9struct FileEntry {
10    name: String,
11    is_directory: bool,
12    extension: Option<String>,
13}
14
15impl FileEntry {
16    fn new(name: &str, is_directory: bool) -> Self {
17        let extension = if is_directory {
18            None
19        } else {
20            std::path::Path::new(name)
21                .extension()
22                .and_then(|ext| ext.to_str())
23                .map(|s| s.to_string())
24        };
25
26        Self {
27            name: name.to_string(),
28            is_directory,
29            extension,
30        }
31    }
32}
33
34fn main() {
35    println!("File Browser Example");
36    println!("===================\n");
37
38    // Sample file entries
39    let files = vec![
40        FileEntry::new("src", true),
41        FileEntry::new("target", true),
42        FileEntry::new("examples", true),
43        FileEntry::new("main.rs", false),
44        FileEntry::new("lib.rs", false),
45        FileEntry::new("Cargo.toml", false),
46        FileEntry::new("README.md", false),
47        FileEntry::new("package.json", false),
48        FileEntry::new("index.html", false),
49        FileEntry::new("style.css", false),
50        FileEntry::new("script.js", false),
51        FileEntry::new("image.png", false),
52        FileEntry::new("document.pdf", false),
53        FileEntry::new("archive.zip", false),
54        FileEntry::new("config.yaml", false),
55        FileEntry::new("data.json", false),
56        FileEntry::new("test.py", false),
57        FileEntry::new("app.go", false),
58        FileEntry::new("component.tsx", false),
59        FileEntry::new("unknown_file", false),
60    ];
61
62    // Display with different themes
63    let themes = vec![
64        ("Minimal (ASCII)", UnicodeTheme::Minimal),
65        ("Rich Unicode", UnicodeTheme::Rich),
66    ];
67
68    for (theme_name, theme) in themes {
69        println!("{} theme:", theme_name);
70        println!("{}:", "─".repeat(theme_name.len() + 7));
71
72        for file in &files {
73            let icon = if file.is_directory {
74                FileType::Directory.get_char(theme)
75            } else if let Some(ext) = &file.extension {
76                let ft = get_file_type_from_extension(ext);
77                ft.get_char(theme)
78            } else {
79                let ft = get_file_type_from_filename(&file.name);
80                ft.get_char(theme)
81            };
82
83            let file_type_name = if file.is_directory {
84                "Directory".to_string()
85            } else if let Some(ext) = &file.extension {
86                let ft = get_file_type_from_extension(ext);
87                format!("{:?}", ft)
88            } else {
89                let ft = get_file_type_from_filename(&file.name);
90                format!("{:?}", ft)
91            };
92
93            println!("  {} {} ({})", icon, file.name, file_type_name);
94        }
95        println!();
96    }
97
98    // Demonstrate language-specific file types
99    println!("Language-specific file types:");
100    println!("============================");
101
102    let theme = UnicodeTheme::Rich;
103    let languages = vec![
104        ("Rust", LanguageType::Rust),
105        ("JavaScript/TypeScript", LanguageType::JavaScript),
106        ("Python", LanguageType::Python),
107        ("Go", LanguageType::Go),
108        ("HTML", LanguageType::Html),
109        ("CSS", LanguageType::Css),
110        ("JSON", LanguageType::Json),
111        ("YAML", LanguageType::Yaml),
112        ("Markdown", LanguageType::Markdown),
113        ("Shell", LanguageType::Shell),
114    ];
115
116    for (name, lang_type) in languages {
117        println!("  {} {}", lang_type.get_char(theme), name);
118    }
119    println!();
120
121    // Create a more realistic file browser display
122    println!("Realistic File Browser Display:");
123    println!("==============================");
124
125    set_global_config(UnicodeConfig::with_theme(UnicodeTheme::Rich));
126
127    println!("📁 /home/user/project");
128    println!("├── {} src/", get_char(&FileType::Directory, None));
129    println!("│   ├── {} main.rs", get_char(&LanguageType::Rust, None));
130    println!("│   ├── {} lib.rs", get_char(&LanguageType::Rust, None));
131    println!("│   └── {} mod.rs", get_char(&LanguageType::Rust, None));
132    println!("├── {} examples/", get_char(&FileType::Directory, None));
133    println!("│   └── {} basic.rs", get_char(&LanguageType::Rust, None));
134    println!("├── {} target/", get_char(&FileType::Directory, None));
135    println!("├── {} Cargo.toml", get_char(&FileType::Config, None));
136    println!("├── {} README.md", get_char(&LanguageType::Markdown, None));
137    println!("├── {} package.json", get_char(&LanguageType::Json, None));
138    println!("└── {} .gitignore", get_char(&FileType::Config, None));
139
140    println!(
141        "\nFile count: {} directories, {} files",
142        files.iter().filter(|f| f.is_directory).count(),
143        files.iter().filter(|f| !f.is_directory).count()
144    );
145}