use crate::color::ColorDepth;
use crate::env::Env;
use crate::icons::{FileKind, GlyphMode, UserFolders, file_kind};
use super::state::ROOT;
use super::{FileManager, parent_key};
#[derive(Debug, Clone, Default)]
pub(super) struct KindLook<'a> {
icons: bool,
tones: bool,
home: Option<(String, &'a UserFolders)>,
}
impl<'a, Msg: Clone + 'static> FileManager<'a, Msg> {
pub(super) fn kind_look(&self, env: &Env) -> KindLook<'a> {
if !self.kind_icons {
return KindLook::default();
}
let tones = self.kind_tones && env.depth() != ColorDepth::Ansi16 && env.glyph_mode() != GlyphMode::Ascii;
let root = self.state.root();
let folders = self.user_folders.or_else(|| {
let home = std::env::var_os("HOME")?;
std::path::Path::new(&home).starts_with(root).then(UserFolders::current).flatten()
});
let home = folders.and_then(|folders| {
let inside = folders.home().strip_prefix(root).ok()?;
let parts: Option<Vec<&str>> = inside.components().map(|part| part.as_os_str().to_str()).collect();
Some((parts?.join("/"), folders))
});
KindLook { icons: true, tones, home }
}
pub(super) fn own_icon(&self, key: &str, name: &str, folder: bool, executable: bool) -> (String, Option<String>) {
let look = &self.kinds;
if !look.icons {
return ((if folder { "folder" } else { "file" }).to_owned(), None);
}
let kind = self.kind_of(key, name, folder, executable);
let tone = if look.tones { kind.family().tone().map(str::to_owned) } else { None };
(kind.icon().to_owned(), tone)
}
fn kind_of(&self, key: &str, name: &str, folder: bool, executable: bool) -> FileKind {
if folder && let Some((home, folders)) = &self.kinds.home {
let own = if key == home {
folders.kind(folders.home())
} else if key != ROOT && parent_key(key) == home {
folders.inside(name)
} else {
None
};
if let Some(kind) = own {
return kind;
}
}
file_kind(name, folder, executable)
}
}