Merge pull request #14 from teohhanhui/riir

Add more scaffolding
This commit is contained in:
Teoh Han Hui 2024-07-03 23:57:18 +08:00 committed by GitHub
commit ff46c8f4ca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 119 additions and 28 deletions

View file

@ -7,7 +7,7 @@ use anyhow::{Context, Result};
use chrono::Datelike; use chrono::Datelike;
use hyfetch::cli_options::options; use hyfetch::cli_options::options;
use hyfetch::models::Config; use hyfetch::models::Config;
use hyfetch::neofetch_util::get_distro_ascii; use hyfetch::neofetch_util::{self, get_distro_ascii};
use hyfetch::presets::AssignLightness; use hyfetch::presets::AssignLightness;
use hyfetch::utils::get_cache_path; use hyfetch::utils::get_cache_path;
use tracing::debug; use tracing::debug;
@ -21,10 +21,15 @@ fn main() -> Result<()> {
// TODO // TODO
// Use a custom distro
let distro = options.distro.as_ref();
// TODO
if options.test_print { if options.test_print {
println!( println!(
"{}", "{}",
get_distro_ascii(options.distro.as_ref()).context("failed to get distro ascii")? get_distro_ascii(distro).context("failed to get distro ascii")?
); );
return Ok(()); return Ok(());
} }
@ -63,7 +68,12 @@ fn main() -> Result<()> {
} }
} }
// TODO // Use a custom distro
let distro = options.distro.as_ref().or(config.distro.as_ref());
let color_mode = options.mode.unwrap_or(config.mode);
let backend = options.backend.unwrap_or(config.backend);
let args = options.args.as_ref().or(config.args.as_ref());
// Get preset // Get preset
let preset = options.preset.unwrap_or(config.preset); let preset = options.preset.unwrap_or(config.preset);
@ -76,11 +86,27 @@ fn main() -> Result<()> {
} else if let Some(lightness) = options.lightness { } else if let Some(lightness) = options.lightness {
color_profile.with_lightness(AssignLightness::Replace(lightness)) color_profile.with_lightness(AssignLightness::Replace(lightness))
} else { } else {
color_profile.with_lightness_dl(config.lightness(), config.light_dark) color_profile.with_lightness_dl(config.lightness(), config.light_dark, options.overlay)
}; };
debug!(?color_profile, "lightened color profile"); debug!(?color_profile, "lightened color profile");
// TODO let asc = if let Some(path) = options.ascii_file {
fs::read_to_string(&path).with_context(|| format!("failed to read ascii from {path:?}"))?
} else {
get_distro_ascii(distro).context("failed to get distro ascii")?
};
let asc = config
.color_align
.recolor_ascii(asc, color_profile, color_mode, config.light_dark);
neofetch_util::run(asc, backend, args).context("failed to run")?;
if options.ask_exit {
print!("Press any key to exit...");
let mut buf = String::new();
io::stdin()
.read_line(&mut buf)
.context("failed to read line from input")?;
}
Ok(()) Ok(())
} }

View file

@ -19,7 +19,7 @@ pub struct Options {
pub preset: Option<Preset>, pub preset: Option<Preset>,
pub mode: Option<AnsiMode>, pub mode: Option<AnsiMode>,
pub backend: Option<Backend>, pub backend: Option<Backend>,
pub args: Vec<String>, pub args: Option<Vec<String>>,
pub scale: Option<f32>, pub scale: Option<f32>,
pub lightness: Option<Lightness>, pub lightness: Option<Lightness>,
pub overlay: bool, pub overlay: bool,
@ -107,7 +107,7 @@ BACKEND={{{}}}",
.help("Additional arguments pass-through to backend") .help("Additional arguments pass-through to backend")
.argument::<String>("ARGS") .argument::<String>("ARGS")
.parse(|s| shell_words::split(&s).context("ARGS should be valid command-line arguments")) .parse(|s| shell_words::split(&s).context("ARGS should be valid command-line arguments"))
.fallback(vec![]); .optional();
let scale = long("c-scale") let scale = long("c-scale")
.help("Lighten colors by a multiplier") .help("Lighten colors by a multiplier")
.argument("SCALE") .argument("SCALE")

View file

@ -13,8 +13,9 @@ pub struct Config {
lightness: Option<Lightness>, lightness: Option<Lightness>,
pub color_align: ColorAlignment, pub color_align: ColorAlignment,
pub backend: Backend, pub backend: Backend,
#[serde(default)]
#[serde(with = "self::args_serde_with")] #[serde(with = "self::args_serde_with")]
pub args: Vec<String>, pub args: Option<Vec<String>>,
pub distro: Option<String>, pub distro: Option<String>,
pub pride_month_disable: bool, pub pride_month_disable: bool,
} }
@ -39,19 +40,27 @@ mod args_serde_with {
use serde::de::{self, value, Deserialize, Deserializer, SeqAccess, Visitor}; use serde::de::{self, value, Deserialize, Deserializer, SeqAccess, Visitor};
use serde::ser::Serializer; use serde::ser::Serializer;
pub(super) fn serialize<S>(value: &Vec<String>, serializer: S) -> Result<S::Ok, S::Error> pub(super) fn serialize<S>(
value: &Option<Vec<String>>,
serializer: S,
) -> Result<S::Ok, S::Error>
where where
S: Serializer, S: Serializer,
{ {
serializer.serialize_str(&shell_words::join(value)) match value {
Some(value) => serializer.serialize_some(&shell_words::join(value)),
None => serializer.serialize_none(),
}
} }
pub(super) fn deserialize<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error> pub(super) fn deserialize<'de, D>(deserializer: D) -> Result<Option<Vec<String>>, D::Error>
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
struct StringOrVec; struct StringOrVec;
struct OptionVisitor;
impl<'de> Visitor<'de> for StringOrVec { impl<'de> Visitor<'de> for StringOrVec {
type Value = Vec<String>; type Value = Vec<String>;
@ -59,13 +68,6 @@ mod args_serde_with {
formatter.write_str("string or list of strings") formatter.write_str("string or list of strings")
} }
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(vec![])
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where where
E: de::Error, E: de::Error,
@ -81,6 +83,38 @@ mod args_serde_with {
} }
} }
deserializer.deserialize_any(StringOrVec) impl<'de> Visitor<'de> for OptionVisitor {
type Value = Option<Vec<String>>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("option")
}
#[inline]
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(None)
}
#[inline]
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(None)
}
#[inline]
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(StringOrVec).map(Some)
}
}
deserializer.deserialize_option(OptionVisitor)
} }
} }

View file

@ -15,12 +15,15 @@ use tracing::debug;
use crate::color_util::{NeofetchAsciiIndexedColor, PresetIndexedColor}; use crate::color_util::{NeofetchAsciiIndexedColor, PresetIndexedColor};
use crate::distros::Distro; use crate::distros::Distro;
use crate::presets::ColorProfile;
use crate::types::{AnsiMode, Backend, LightDark};
const NEOFETCH_COLOR_PATTERN: &str = r"\$\{c[0-9]\}"; const NEOFETCH_COLOR_PATTERN: &str = r"\$\{c[0-6]\}";
static NEOFETCH_COLOR_RE: OnceLock<Regex> = OnceLock::new(); static NEOFETCH_COLOR_RE: OnceLock<Regex> = OnceLock::new();
#[derive(Clone, Eq, PartialEq, Debug, Deserialize, Serialize)] #[derive(Clone, Eq, PartialEq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase", tag = "mode")] #[serde(tag = "mode")]
#[serde(rename_all = "lowercase")]
pub enum ColorAlignment { pub enum ColorAlignment {
Horizontal { Horizontal {
fore_back: Option<(NeofetchAsciiIndexedColor, NeofetchAsciiIndexedColor)>, fore_back: Option<(NeofetchAsciiIndexedColor, NeofetchAsciiIndexedColor)>,
@ -34,6 +37,19 @@ pub enum ColorAlignment {
}, },
} }
impl ColorAlignment {
/// Uses the color alignment to recolor an ascii art.
pub fn recolor_ascii(
&self,
asc: String,
color_profile: ColorProfile,
color_mode: AnsiMode,
term: LightDark,
) -> String {
todo!()
}
}
/// Gets the absolute path of the neofetch command. /// Gets the absolute path of the neofetch command.
pub fn get_command_path() -> Result<PathBuf> { pub fn get_command_path() -> Result<PathBuf> {
if let Ok(workspace_dir) = env::var("CARGO_WORKSPACE_DIR") { if let Ok(workspace_dir) = env::var("CARGO_WORKSPACE_DIR") {
@ -93,6 +109,10 @@ where
todo!() todo!()
} }
pub fn run(asc: String, backend: Backend, args: Option<&Vec<String>>) -> Result<()> {
todo!()
}
/// Gets distro ascii width and height, ignoring color code. /// Gets distro ascii width and height, ignoring color code.
pub fn ascii_size<S>(asc: S) -> (u8, u8) pub fn ascii_size<S>(asc: S) -> (u8, u8)
where where
@ -101,9 +121,7 @@ where
let asc = asc.as_ref(); let asc = asc.as_ref();
let Some(width) = NEOFETCH_COLOR_RE let Some(width) = NEOFETCH_COLOR_RE
.get_or_init(|| { .get_or_init(|| Regex::new(NEOFETCH_COLOR_PATTERN).unwrap())
Regex::new(NEOFETCH_COLOR_PATTERN).expect("neofetch color regex should not be invalid")
})
.replace_all(asc, "") .replace_all(asc, "")
.split('\n') .split('\n')
.map(|line| line.len()) .map(|line| line.len())

View file

@ -484,7 +484,16 @@ impl ColorProfile {
/// Creates a new color profile, with the colors set to the specified HSL /// Creates a new color profile, with the colors set to the specified HSL
/// lightness value, with respect to dark/light terminals. /// lightness value, with respect to dark/light terminals.
pub fn with_lightness_dl(&self, lightness: Lightness, term: LightDark) -> Self { pub fn with_lightness_dl(
&self,
lightness: Lightness,
term: LightDark,
use_overlay: bool,
) -> Self {
if use_overlay {
todo!()
}
match term { match term {
LightDark::Dark => self.with_lightness(AssignLightness::ClampMin(lightness)), LightDark::Dark => self.with_lightness(AssignLightness::ClampMin(lightness)),
LightDark::Light => self.with_lightness(AssignLightness::ClampMax(lightness)), LightDark::Light => self.with_lightness(AssignLightness::ClampMax(lightness)),

View file

@ -1,7 +1,9 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use strum::{EnumString, VariantNames}; use strum::{EnumString, VariantNames};
#[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize, EnumString, Serialize, VariantNames)] #[derive(
Copy, Clone, Eq, PartialEq, Hash, Debug, Deserialize, EnumString, Serialize, VariantNames,
)]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
#[strum(serialize_all = "lowercase")] #[strum(serialize_all = "lowercase")]
pub enum AnsiMode { pub enum AnsiMode {
@ -11,14 +13,16 @@ pub enum AnsiMode {
Rgb, Rgb,
} }
#[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize, Serialize)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
pub enum LightDark { pub enum LightDark {
Light, Light,
Dark, Dark,
} }
#[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize, EnumString, Serialize, VariantNames)] #[derive(
Copy, Clone, Eq, PartialEq, Hash, Debug, Deserialize, EnumString, Serialize, VariantNames,
)]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
#[strum(serialize_all = "kebab-case")] #[strum(serialize_all = "kebab-case")]
pub enum Backend { pub enum Backend {