Skip to content

Commit 8e11637

Browse files
authored
release v1.3.0 (#20)
- Resolves #14 ## Proposed Changes - `--stdin` command line option for reading ASCII art from stdin - option for setting spacing between art and info block - fixed odd looking uptime of only days and minutes are there ## Tested on - [ ] Linux; Distro(s): - [x] MacOS
2 parents 926d4cc + 3e9b523 commit 8e11637

9 files changed

Lines changed: 100 additions & 65 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "nerdfetch-rs"
3-
version = "1.2.2"
3+
version = "1.3.0"
44
authors = ["minomy13 <mail@minomy13.com>"]
55
edition = "2024"
66
description = "A minimal, fast system fetch tool - rewritten in Rust for speed, clarity, and configurability."

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ This project is a Rust-based reimagining with a similar aesthetic and minimalist
3333

3434
<br>ASCII arts by [Hayley Jane Wakenshaw](https://asciiart.website/art/1652) and an [unknown artist](https://emojicombos.com/pokemon-ascii-art).
3535

36+
## Command line options
37+
38+
- `--stdin` - read ASCII art from stdin, e.g. `cat art.txt | nerdfetch-rs --stdin`
39+
3640
## Config
3741

3842
You can find the config file at `$HOME/.config/nerdfetch-rs.toml`. As the suffix might suggest, it is in TOML format.

src/config.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
mod default;
1+
pub mod default;
22
pub mod schema;
33

44
use crate::config::schema::Config;
@@ -17,8 +17,8 @@ macro_rules! conf_unwrap_or {
1717
};
1818

1919
($conf:ident, $or:expr, $name:ident) => {
20-
if let Some($name) = $conf.$name {
21-
$name
20+
if let Some($name) = &$conf.$name {
21+
$name.to_owned()
2222
} else { $or }
2323
}
2424
}

src/config/default.rs

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,7 @@
1-
use crate::config::schema::{Color, Theme};
2-
3-
impl Default for Theme {
4-
fn default() -> Self {
5-
Self {
6-
ascii_art: String::from(
7-
r" ___
1+
pub const ASCII_TUX: &str = r" ___
82
(.. \
93
(<> |
104
// \ \
115
( | | /|
126
_/\ __)/_)
13-
\/-____\/",
14-
),
15-
art_color: None,
16-
icon_color: Color::BrightMagenta,
17-
info_color: Color::Green,
18-
}
19-
}
20-
}
7+
\/-____\/";

src/config/schema.rs

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
22

33
#[derive(Default, Serialize, Deserialize, Debug)]
44
pub struct Config {
5-
pub theme: Theme,
5+
pub theme: Option<Theme>,
66
pub modules: Option<Modules>,
77
}
88

@@ -65,10 +65,11 @@ pub struct UserConfig {
6565

6666
#[derive(Serialize, Deserialize, Debug)]
6767
pub struct Theme {
68-
pub ascii_art: String,
68+
pub ascii_art: Option<String>,
6969
pub art_color: Option<Color>,
70-
pub icon_color: Color,
71-
pub info_color: Color,
70+
pub icon_color: Option<Color>,
71+
pub info_color: Option<Color>,
72+
pub art_info_spacing: Option<usize>,
7273
}
7374

7475
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
@@ -81,6 +82,7 @@ pub enum Alignment {
8182
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
8283
#[serde(rename_all = "snake_case")]
8384
pub enum Color {
85+
Reset = 0,
8486
White = 37,
8587
Black = 30,
8688
Red = 31,
@@ -96,31 +98,3 @@ pub enum Color {
9698
BrightMagenta = 95,
9799
BrightCyan = 96,
98100
}
99-
100-
impl Theme {
101-
pub fn get_fmt_art_longest_ln(&self) -> usize {
102-
let mut longest_line = 0;
103-
for line in self.ascii_art.lines() {
104-
let len = line.len();
105-
if len > longest_line {
106-
longest_line = len
107-
}
108-
}
109-
longest_line
110-
}
111-
112-
pub fn get_formatted_ascii_art(&self) -> String {
113-
let mut result = String::new();
114-
115-
let longest_line = self.get_fmt_art_longest_ln();
116-
117-
for line in self.ascii_art.lines() {
118-
result.push_str(&format!(
119-
"{line}{}\n",
120-
" ".repeat(longest_line - line.len())
121-
))
122-
}
123-
124-
result
125-
}
126-
}

src/main.rs

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,46 @@
1-
use crate::config::{conf_unwrap_or, schema::Alignment};
1+
use std::{env, io::stdin};
2+
3+
use crate::{
4+
config::{
5+
conf_unwrap_or,
6+
default::ASCII_TUX,
7+
schema::{Alignment, Color},
8+
},
9+
util::{format_ascii_art, get_fmt_line_len},
10+
};
211

312
mod config;
413
mod modules;
14+
mod util;
515

616
fn main() {
717
let config = config::read();
818

9-
let ascii_art = config.theme.get_formatted_ascii_art();
19+
let args: Vec<String> = env::args().collect();
20+
21+
let ascii_art = if args.len() > 1 && args.contains(&"--stdin".to_string()) {
22+
let mut buf = String::new();
23+
loop {
24+
let bytes = stdin()
25+
.read_line(&mut buf)
26+
.expect("Couldn't read from stdin");
27+
if bytes == 0 {
28+
break;
29+
}
30+
}
31+
buf
32+
} else {
33+
conf_unwrap_or!(config, ASCII_TUX.to_owned(), theme / ascii_art).to_owned()
34+
};
35+
let ascii_art = format_ascii_art(ascii_art);
36+
1037
let modules = modules::get_modules(&config);
1138

1239
let mut lines = vec![];
1340

1441
for line in ascii_art.lines() {
15-
if let Some(color) = &config.theme.art_color {
16-
lines.push(format!("\x1b[{}m {line}\x1b[0m", color.to_owned() as u32))
17-
} else {
18-
lines.push(format!(" {line}"))
19-
}
42+
let color = conf_unwrap_or!(config, Color::Reset, theme / art_color);
43+
lines.push(format!("\x1b[{}m {line}\x1b[0m", color.to_owned() as u32));
2044
}
2145

2246
let modules_start = match conf_unwrap_or!(config, Alignment::Top, modules / alignment) {
@@ -30,12 +54,19 @@ fn main() {
3054
}
3155
};
3256

57+
let longest_art_line = get_fmt_line_len(lines.first().unwrap_or(&"".to_string()));
3358
for i in 0..modules.len() {
59+
let spacing = conf_unwrap_or!(config, 2, theme / art_info_spacing);
60+
3461
match lines.get_mut(i + modules_start) {
35-
Some(line) => line.push_str(&format!(" {}", modules.get(i).unwrap())),
62+
Some(line) => line.push_str(&format!(
63+
"{}{}",
64+
" ".repeat(spacing),
65+
modules.get(i).unwrap()
66+
)),
3667
None => lines.push(format!(
37-
" {}{}",
38-
" ".repeat(config.theme.get_fmt_art_longest_ln()),
68+
"{}{}",
69+
" ".repeat(spacing + longest_art_line),
3970
modules.get(i).unwrap()
4071
)),
4172
}

src/modules/module.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
use crate::config::schema::Config;
1+
use crate::{
2+
conf_unwrap_or,
3+
config::schema::{Color, Config},
4+
};
25

36
pub trait Module {
47
fn get_formatted(&self, config: &Config) -> String {
58
format!(
69
"\x1b[0m\x1b[{}m{} \x1b[0m\x1b[{}m{}\x1b[0m",
7-
config.theme.icon_color.to_owned() as u32,
10+
conf_unwrap_or!(config, Color::BrightMagenta, theme / icon_color) as u32,
811
self.get_icon(config),
9-
config.theme.info_color.to_owned() as u32,
12+
conf_unwrap_or!(config, Color::Green, theme / info_color) as u32,
1013
self.get_info(config)
1114
)
1215
}

src/modules/uptime.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ impl Module for Uptime {
2020
format!(
2121
"{}{}{}",
2222
if days > 0 {
23-
format!("{days} days{}", if hours > 0 { ", " } else { "" })
23+
format!(
24+
"{days} days{}",
25+
if hours > 0 || minutes > 0 { ", " } else { "" }
26+
)
2427
} else {
2528
"".to_string()
2629
},

src/util.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
use regex::Regex;
2+
3+
// TODO: don't call twice
4+
pub fn get_fmt_line_len(line: &str) -> usize {
5+
let ansi_code_pattern = Regex::new(r"\u{1b}?\[[\d+;]+m").unwrap();
6+
ansi_code_pattern.replace_all(line, "").chars().count()
7+
}
8+
9+
fn get_longest_ln(str: &str) -> usize {
10+
let mut longest_line = 0;
11+
for line in str.lines() {
12+
let len = get_fmt_line_len(line);
13+
if len > longest_line {
14+
longest_line = len
15+
}
16+
}
17+
longest_line
18+
}
19+
20+
pub fn format_ascii_art(str: String) -> String {
21+
let mut result = String::new();
22+
23+
let longest_line = get_longest_ln(&str);
24+
25+
for line in str.lines() {
26+
result.push_str(&format!(
27+
"{line}{}\n",
28+
" ".repeat(longest_line - get_fmt_line_len(line))
29+
))
30+
}
31+
32+
result
33+
}

0 commit comments

Comments
 (0)