refactor: extract constants

This commit is contained in:
🪞👃🪞 2025-04-06 19:32:29 +03:00
parent 84f183ab84
commit 36423fc994
7 changed files with 65 additions and 52 deletions

43
src/constants.rs Normal file
View file

@ -0,0 +1,43 @@
use crate::*;
pub(crate) const PAGE_SIZE: usize = 10;
macro_rules! bytes {
($name:ident $value:expr) => { pub(crate) const $name: &'static [u8] = $value; }
}
macro_rules! string {
($name:ident $value:expr) => { pub(crate) const $name: &'static str = $value; }
}
macro_rules! color {
($name:ident $value:expr) => { pub(crate) const $name: Color = $value; }
}
bytes!(MAGIC_PNG &[0x89, b'P', b'N', b'G', 0x0D, 0x0A, 0x1A, 0x0A]);
bytes!(MAGIC_JPG_1 &[0xFF, 0xD8, 0xFF, 0xDB]);
bytes!(MAGIC_JPG_2 &[0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01]);
bytes!(MAGIC_JPG_3 &[0xFF, 0xD8, 0xFF, 0xEE]);
bytes!(MAGIC_JPG_4A &[0xFF, 0xD8, 0xFF, 0xE1]);
string!(ICON_DIRECTORY "");
string!(ICON_IMAGE "󰋩");
string!(ICON_MUSIC "");
string!(ICON_MUSIC_NO_META "󰎇");
string!(ICON_UNKNOWN "");
string!(ICON_SCROLL_LEFT "");
string!(ICON_SCROLL_RIGHT "");
color!(FG_MODAL Color::Rgb(255, 255, 255));
color!(BG_MODAL Color::Rgb(0, 0, 0));
color!(FG_BROWSE Color::Rgb(255, 192, 0));
color!(BG_COLUMN Color::Rgb(0, 0, 0));
color!(FG_ROW Color::Rgb(0, 0, 0));
color!(BG_ROW Color::Rgb(192, 128, 0));
color!(BG_CELL Color::Rgb(224, 192, 0));
color!(FG_CELL Color::Rgb(255, 255, 255));
color!(BG_EDIT Color::Rgb(48, 96, 0));
color!(FG_EDIT Color::Rgb(255, 255, 255));
color!(BG_BROWSE Color::Rgb(0, 0, 0));
color!(BG_SAVE Color::Rgb(192, 96, 0));
color!(FG_SAVE Color::Rgb(255, 255, 255));
color!(BG_QUIT Color::Rgb(128, 0, 0));
color!(FG_QUIT Color::Rgb(255, 255, 255));

View file

@ -18,12 +18,11 @@ use xxhash_rust::xxh3::xxh3_64;
mod keys; mod keys;
mod view; use self::view::*; mod view; use self::view::*;
mod model; pub(crate) use self::model::*; mod model; pub(crate) use self::model::*;
mod constants; pub(crate) use self::constants::*;
pub(crate) type Usually<T> = std::result::Result<T, Box<dyn std::error::Error>>; pub(crate) type Usually<T> = std::result::Result<T, Box<dyn std::error::Error>>;
pub(crate) type Perhaps<T> = Usually<Option<T>>; pub(crate) type Perhaps<T> = Usually<Option<T>>;
pub(crate) const PAGE_SIZE: usize = 10;
fn cli () -> clap::Command { fn cli () -> clap::Command {
command!() command!()
.arg(arg!([path] "Path to root directory") .arg(arg!([path] "Path to root directory")

View file

@ -58,11 +58,6 @@ pub(crate) fn entries_under (
pub struct Columns<G, S>(pub Vec<Column<G, S>>); pub struct Columns<G, S>(pub Vec<Column<G, S>>);
impl<G, S> Columns<G, S> {
const SCROLL_LEFT: &'static str = "";
const SCROLL_RIGHT: &'static str = "";
}
macro_rules! setter { macro_rules! setter {
($set:ident) => {{ ($set:ident) => {{
fn $set (state: &mut Taggart, index: usize, value: &str) { fn $set (state: &mut Taggart, index: usize, value: &str) {

View file

@ -20,11 +20,6 @@ pub struct Entry {
} }
impl Entry { impl Entry {
pub const ICON_DIRECTORY: &'static str = "";
pub const ICON_IMAGE: &'static str = "󰋩";
pub const ICON_MUSIC: &'static str = "";
pub const ICON_MUSIC_NO_META: &'static str = "󰎇";
pub const ICON_UNKNOWN: &'static str = "";
pub fn new (root: &impl AsRef<Path>, path: &impl AsRef<Path>, depth: usize) -> Perhaps<Self> { pub fn new (root: &impl AsRef<Path>, path: &impl AsRef<Path>, depth: usize) -> Perhaps<Self> {
let path = path.as_ref(); let path = path.as_ref();
if path.is_dir() { if path.is_dir() {
@ -71,13 +66,13 @@ impl Entry {
} }
fn icon (&self) -> &'static str { fn icon (&self) -> &'static str {
if self.is_directory() { if self.is_directory() {
Self::ICON_DIRECTORY ICON_DIRECTORY
} else if self.is_image() { } else if self.is_image() {
Self::ICON_IMAGE ICON_IMAGE
} else if self.is_music() { } else if self.is_music() {
Self::ICON_MUSIC ICON_MUSIC
} else { } else {
Self::ICON_UNKNOWN ICON_UNKNOWN
} }
} }
pub fn is_modified (&self) -> bool { pub fn is_modified (&self) -> bool {
@ -156,7 +151,7 @@ impl Metadata {
let mut bytes = vec![0;16]; let mut bytes = vec![0;16];
reader.read(&mut bytes)?; reader.read(&mut bytes)?;
// PNG // PNG
if bytes.starts_with(&[0x89, b'P', b'N', b'G', 0x0D, 0x0A, 0x1A, 0x0A]) { if bytes.starts_with(MAGIC_PNG) {
let mut bytes = vec![]; let mut bytes = vec![];
BufReader::new(File::open(path)?).read(&mut bytes)?; BufReader::new(File::open(path)?).read(&mut bytes)?;
return Ok(Self::Image { return Ok(Self::Image {
@ -168,12 +163,10 @@ impl Metadata {
}) })
} }
// JPG // JPG
if bytes.starts_with(&[0xFF, 0xD8, 0xFF, 0xDB]) if bytes.starts_with(MAGIC_JPG_1)
|| bytes.starts_with(&[0xFF, 0xD8, 0xFF, 0xE0, || bytes.starts_with(MAGIC_JPG_2)
0x00, 0x10, 0x4A, 0x46, || bytes.starts_with(MAGIC_JPG_3)
0x49, 0x46, 0x00, 0x01]) || (bytes.starts_with(MAGIC_JPG_4A) &&
|| bytes.starts_with(&[0xFF, 0xD8, 0xFF, 0xEE])
|| (bytes.starts_with(&[0xFF, 0xD8, 0xFF, 0xE1]) &&
bytes.get(6) == Some(&0x45) && bytes.get(7) == Some(&0x78) && bytes.get(6) == Some(&0x45) && bytes.get(7) == Some(&0x78) &&
bytes.get(8) == Some(&0x69) && bytes.get(9) == Some(&0x66) && bytes.get(8) == Some(&0x69) && bytes.get(9) == Some(&0x66) &&
bytes.get(10) == Some(&0x00) && bytes.get(11) == Some(&0x00)) bytes.get(10) == Some(&0x00) && bytes.get(11) == Some(&0x00))

View file

@ -1,11 +1,9 @@
use crate::*; use crate::*;
impl Taggart { impl Taggart {
pub(crate) const FG_MODAL: Color = Color::Rgb(255, 255, 255);
pub(crate) const BG_MODAL: Color = Color::Rgb(0, 0, 0);
fn dialog (content: impl Content<TuiOut>) -> impl Content<TuiOut> { fn dialog (content: impl Content<TuiOut>) -> impl Content<TuiOut> {
let pos = |x|Fill::xy( Align::c(x)); let pos = |x|Fill::xy( Align::c(x));
let style = |x|Tui::modify(false, Modifier::DIM, Tui::fg_bg(Self::FG_MODAL, Self::BG_MODAL, x)); let style = |x|Tui::modify(false, Modifier::DIM, Tui::fg_bg(FG_MODAL, BG_MODAL, x));
let border = |x|Margin::xy(1, 1, Bsp::b(Border(true, Lozenge(true, Default::default())), x)); let border = |x|Margin::xy(1, 1, Bsp::b(Border(true, Lozenge(true, Default::default())), x));
let bg = |x|Bsp::a(x, Repeat(" ")); let bg = |x|Bsp::a(x, Repeat(" "));
pos(style(border(bg(content)))) pos(style(border(bg(content))))

View file

@ -1,14 +1,6 @@
use crate::*; use crate::*;
impl Taggart { impl Taggart {
pub(crate) const FG_BROWSE: Color = Color::Rgb(255, 192, 0);
pub(crate) const BG_BROWSE: Color = Color::Rgb(0, 0, 0);
pub(crate) const BG_EDIT: Color = Color::Rgb(48, 128, 0);
pub(crate) const FG_EDIT: Color = Color::Rgb(255, 255, 255);
pub(crate) const BG_SAVE: Color = Color::Rgb(192, 96, 0);
pub(crate) const FG_SAVE: Color = Color::Rgb(255, 255, 255);
pub(crate) const BG_QUIT: Color = Color::Rgb(128, 0, 0);
pub(crate) const FG_QUIT: Color = Color::Rgb(255, 255, 255);
pub(crate) fn title_bar (&self) -> impl Content<TuiOut> { pub(crate) fn title_bar (&self) -> impl Content<TuiOut> {
status_bar( status_bar(
Color::Rgb(0, 0, 0), Color::Rgb(0, 0, 0),
@ -40,10 +32,10 @@ impl Taggart {
} }
pub(crate) fn mode_bar (&self, size: String) -> impl Content<TuiOut> { pub(crate) fn mode_bar (&self, size: String) -> impl Content<TuiOut> {
let mode = match self.mode { let mode = match self.mode {
Some(Mode::Save { .. }) => Tui::bg(Self::BG_SAVE, Tui::fg(Self::FG_SAVE, " SAVE ")), Some(Mode::Save { .. }) => Tui::bg(BG_SAVE, Tui::fg(FG_SAVE, " SAVE ")),
Some(Mode::Quit { .. }) => Tui::bg(Self::BG_QUIT, Tui::fg(Self::FG_QUIT, " QUIT ")), Some(Mode::Quit { .. }) => Tui::bg(BG_QUIT, Tui::fg(FG_QUIT, " QUIT ")),
Some(Mode::Edit { .. }) => Tui::bg(Self::BG_EDIT, Tui::fg(Self::FG_EDIT, " EDIT ")), Some(Mode::Edit { .. }) => Tui::bg(BG_EDIT, Tui::fg(FG_EDIT, " EDIT ")),
_ => Tui::bg(Self::BG_BROWSE, Tui::fg(Self::FG_BROWSE, " BROWSE ")) _ => Tui::bg(BG_BROWSE, Tui::fg(FG_BROWSE, " BROWSE "))
}; };
let help = match self.mode { let help = match self.mode {
Some(Mode::Save { .. }) => " Esc: cancel, Arrows: select, Enter: confirm", Some(Mode::Save { .. }) => " Esc: cancel, Arrows: select, Enter: confirm",

View file

@ -14,13 +14,6 @@ impl<'a> Content<TuiOut> for TreeTable<'a> {
} }
impl<'a> TreeTable<'a> { impl<'a> TreeTable<'a> {
pub(crate) const BG_COLUMN: Color = Color::Rgb(0, 0, 0);
pub(crate) const FG_ROW: Color = Color::Rgb(0, 0, 0);
pub(crate) const BG_ROW: Color = Color::Rgb(192, 128, 0);
pub(crate) const BG_CELL: Color = Color::Rgb(224, 192, 0);
pub(crate) const FG_CELL: Color = Color::Rgb(255, 255, 255);
pub(crate) const BG_EDIT: Color = Color::Rgb(48, 96, 0);
pub(crate) const FG_EDIT: Color = Color::Rgb(255, 255, 255);
fn rows (&self, to: &mut TuiOut, area: [u16;4], active_x: u16, active_w: u16) { fn rows (&self, to: &mut TuiOut, area: [u16;4], active_x: u16, active_w: u16) {
for (row_index, row_y) in area.iter_y().enumerate() { for (row_index, row_y) in area.iter_y().enumerate() {
let row_index_scrolled = row_index + self.0.offset; let row_index_scrolled = row_index + self.0.offset;
@ -44,16 +37,16 @@ impl<'a> TreeTable<'a> {
} }
} }
fn column_cursor (to: &mut TuiOut, area: [u16;4], active_x: u16, active_w: u16) { fn column_cursor (to: &mut TuiOut, area: [u16;4], active_x: u16, active_w: u16) {
to.fill_bg([area.x() + active_x, area.y(), active_w, area.h()], Self::BG_COLUMN); to.fill_bg([area.x() + active_x, area.y(), active_w, area.h()], BG_COLUMN);
} }
fn row_cursor (to: &mut TuiOut, x: u16, y: u16, w: u16) { fn row_cursor (to: &mut TuiOut, x: u16, y: u16, w: u16) {
let fill = [x, y, w, 1]; let fill = [x, y, w, 1];
to.fill_fg(fill, Self::FG_ROW); to.fill_fg(fill, FG_ROW);
to.fill_bg(fill, Self::BG_ROW); to.fill_bg(fill, BG_ROW);
} }
fn cell_cursor (&self, to: &mut TuiOut, xa: u16, x0: u16, y: u16, w: u16) { fn cell_cursor (&self, to: &mut TuiOut, xa: u16, x0: u16, y: u16, w: u16) {
let fill = [xa + x0, y, w, 1]; let fill = [xa + x0, y, w, 1];
to.fill_bg(fill, Self::BG_CELL); to.fill_bg(fill, BG_CELL);
} }
fn row_data (&self, to: &mut TuiOut, entry: &Entry, cursor: usize, x: &mut u16) { fn row_data (&self, to: &mut TuiOut, entry: &Entry, cursor: usize, x: &mut u16) {
let y = to.area().y(); let y = to.area().y();
@ -65,14 +58,14 @@ impl<'a> TreeTable<'a> {
&& self.0.column == column_index && self.0.column == column_index
&& self.0.cursor == cursor && self.0.cursor == cursor
{ {
to.fill_bg([*x, y, width as u16, 1], Self::BG_EDIT); to.fill_bg([*x, y, width as u16, 1], BG_EDIT);
to.fill_fg([*x, y, width as u16, 1], Self::FG_EDIT); to.fill_fg([*x, y, width as u16, 1], FG_EDIT);
to.fill_reversed([*x + *edit_index as u16, y, 1, 1], true); to.fill_reversed([*x + *edit_index as u16, y, 1, 1], true);
Content::render(&TrimStringRef(width as u16, &value), to); Content::render(&TrimStringRef(width as u16, &value), to);
} else if let Some(value) = getter(entry) { } else if let Some(value) = getter(entry) {
Content::render(&TrimStringRef(width as u16, &value), to); Content::render(&TrimStringRef(width as u16, &value), to);
if self.0.cursor != cursor { if self.0.cursor != cursor {
to.fill_fg([*x, y, width as u16, 1], Self::FG_CELL); to.fill_fg([*x, y, width as u16, 1], FG_CELL);
} }
} }
*x += width as u16 + 1; *x += width as u16 + 1;