This commit is contained in:
Xithrius 2022-10-01 17:34:42 -07:00 committed by GitHub
parent 87d7b8892f
commit 9e2c98b747
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 133 additions and 105 deletions

View File

@ -1,20 +0,0 @@
name: Greetings
on:
pull_request:
branches: [ main ]
issues:
branches: [ main ]
jobs:
greeting:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/first-interaction@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
issue-message: 'Thank you for the issue! This issue will be addressed in a reasonable amount of time.'
pr-message: 'Thank you for the pull request! This contribution will be addressed in a reasonable amount of time.'

51
Cargo.lock generated
View File

@ -120,26 +120,24 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "3.2.20" version = "4.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b71c3ce99b7611011217b366d923f1d0a7e07a92bb2dbf1e84508c673ca3bd" checksum = "0a1af219c3e254a8b4649d6ddaef886b2015089f35f2ac5e1db31410c0566ab8"
dependencies = [ dependencies = [
"atty", "atty",
"bitflags", "bitflags",
"clap_derive", "clap_derive",
"clap_lex", "clap_lex",
"indexmap",
"once_cell", "once_cell",
"strsim", "strsim",
"termcolor", "termcolor",
"textwrap",
] ]
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "3.2.18" version = "4.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" checksum = "cd114ae53ce5a0670f43d2f169c1cd26c69b4896b0c121900cf1e4d06d67316c"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro-error", "proc-macro-error",
@ -150,9 +148,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_lex" name = "clap_lex"
version = "0.2.4" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
dependencies = [ dependencies = [
"os_str_bytes", "os_str_bytes",
] ]
@ -527,12 +525,6 @@ version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.4.0" version = "0.4.0"
@ -568,16 +560,6 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
[[package]]
name = "indexmap"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]] [[package]]
name = "instant" name = "instant"
version = "0.1.12" version = "0.1.12"
@ -960,9 +942,9 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.40" version = "1.0.46"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -1269,9 +1251,9 @@ dependencies = [
[[package]] [[package]]
name = "textwrap" name = "textwrap"
version = "0.15.0" version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16"
dependencies = [ dependencies = [
"smawk", "smawk",
"unicode-linebreak", "unicode-linebreak",
@ -1320,9 +1302,9 @@ dependencies = [
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.20.0" version = "1.21.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57aec3cfa4c296db7255446efb4928a6be304b431a806216105542a67b6ca82e" checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"bytes", "bytes",
@ -1330,7 +1312,6 @@ dependencies = [
"memchr", "memchr",
"mio", "mio",
"num_cpus", "num_cpus",
"once_cell",
"parking_lot 0.12.1", "parking_lot 0.12.1",
"pin-project-lite", "pin-project-lite",
"signal-hook-registry", "signal-hook-registry",
@ -1492,15 +1473,15 @@ dependencies = [
[[package]] [[package]]
name = "unicode-segmentation" name = "unicode-segmentation"
version = "1.9.0" version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"
version = "0.1.9" version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
[[package]] [[package]]
name = "utf8parse" name = "utf8parse"

View File

@ -15,17 +15,17 @@ categories = ["command-line-utilities"]
[dependencies] [dependencies]
crossterm = "0.25.0" crossterm = "0.25.0"
tui = { version = "0.19.0", default-features = false, features = [ "crossterm" ] } tui = { version = "0.19.0", default-features = false, features = [ "crossterm" ] }
tokio = { version = "1.20.0", features = [ "full" ] } tokio = { version = "1.21.1", features = [ "full" ] }
clap = { version = "3.2.13", features = [ "derive", "cargo" ] } clap = { version = "4.0.7", features = [ "derive", "cargo" ] }
serde = { version = "1.0.140", features = [ "derive" ] } serde = { version = "1.0.144", features = [ "derive" ] }
serde_json = "1.0.82" serde_json = "1.0.85"
unicode-width = "0.1.9" unicode-width = "0.1.10"
unicode-segmentation = "1.9.0" unicode-segmentation = "1.10.0"
chrono = "0.4" chrono = "0.4.22"
irc = "0.15.0" irc = "0.15.0"
futures = "0.3.21" futures = "0.3.24"
toml = "0.5.9" toml = "0.5.9"
textwrap = "0.15.0" textwrap = "0.15.1"
rustyline = "10.0.0" rustyline = "10.0.0"
lazy_static = "1.4.0" lazy_static = "1.4.0"
fuzzy-matcher = "0.3.7" fuzzy-matcher = "0.3.7"

View File

@ -1,47 +1,87 @@
use std::str::FromStr; use clap::{builder::PossibleValue, Parser};
use clap::Parser; use crate::handlers::config::{Alignment, CompleteConfig, Palette, Theme};
use crate::handlers::config::{CompleteConfig, Palette, Theme}; impl clap::ValueEnum for Alignment {
fn value_variants<'a>() -> &'a [Self] {
&[Self::Left, Self::Center, Self::Right]
}
#[derive(Parser)] fn to_possible_value<'a>(&self) -> Option<PossibleValue> {
Some(PossibleValue::new(match self {
Self::Left => "left",
Self::Center => "center",
Self::Right => "right",
}))
}
}
impl clap::ValueEnum for Palette {
fn value_variants<'a>() -> &'a [Self] {
&[Self::Pastel, Self::Vibrant, Self::Warm, Self::Cool]
}
fn to_possible_value<'a>(&self) -> Option<PossibleValue> {
Some(PossibleValue::new(match self {
Self::Pastel => "pastel",
Self::Vibrant => "vibrant",
Self::Warm => "warm",
Self::Cool => "cool",
}))
}
}
impl clap::ValueEnum for Theme {
fn value_variants<'a>() -> &'a [Self] {
&[Self::Dark, Self::Light]
}
fn to_possible_value<'a>(&self) -> Option<PossibleValue> {
Some(PossibleValue::new(match self {
Self::Light => "light",
_ => "dark",
}))
}
}
#[derive(Parser, Debug)]
#[clap(rename_all = "kebab-case")] #[clap(rename_all = "kebab-case")]
#[clap(author, version, about)] #[clap(author, version, about)]
/// Twitch chat in the terminal /// Twitch chat in the terminal
pub struct Cli { pub struct Cli {
/// The streamer's name /// The streamer's name
#[clap(short, long)] #[arg(short, long)]
pub channel: Option<String>, pub channel: Option<String>,
/// File to log to /// File to log to
#[clap(short, long)] #[arg(short, long)]
pub log_file: Option<String>, pub log_file: Option<String>,
/// If debug logs should be shown /// If debug logs should be shown
#[clap(short, long)] #[arg(short, long)]
pub verbose: bool, pub verbose: bool,
/// The delay in milliseconds between terminal updates /// The delay in milliseconds between terminal updates
#[clap(short, long)] #[arg(short, long)]
pub tick_delay: Option<u64>, pub tick_delay: Option<u64>,
/// The maximum amount of messages to be stored /// The maximum amount of messages to be stored
#[clap(short, long)] #[arg(short, long)]
pub max_messages: Option<usize>, pub max_messages: Option<usize>,
/// Show the date/time /// Show the date/time
#[clap(short, long, possible_values = &["true", "false"])] #[arg(short, long)]
pub date_shown: Option<String>, pub date_shown: bool,
/// Maximum length for Twitch usernames /// Maximum length for Twitch usernames
#[clap(short = 'u', long)] #[arg(short = 'u', long)]
pub max_username_length: Option<u16>, pub max_username_length: Option<u16>,
/// Username column alignment /// Username column alignment
#[clap(short = 'a', long, possible_values = &["left", "center", "right"])] #[arg(short = 'a', long)]
pub username_alignment: Option<String>, pub username_alignment: Option<Alignment>,
/// Username color palette /// Username color palette
#[clap(short, long, possible_values = &["pastel", "vibrant", "warm", "cool"])] #[arg(short, long)]
pub palette: Option<Palette>, pub palette: Option<Palette>,
/// Twitch badges support /// Twitch badges support
#[clap(short, long)] #[arg(short, long)]
pub badges: bool, pub badges: bool,
/// The theme of the terminal /// The theme of the terminal
#[clap(long, possible_values = &["dark", "light"])] #[arg(long)]
pub theme: Option<String>, pub theme: Option<Theme>,
} }
pub fn merge_args_into_config(config: &mut CompleteConfig, args: Cli) { pub fn merge_args_into_config(config: &mut CompleteConfig, args: Cli) {
@ -64,9 +104,8 @@ pub fn merge_args_into_config(config: &mut CompleteConfig, args: Cli) {
} }
// Frontend arguments // Frontend arguments
if let Some(date_shown) = args.date_shown { config.frontend.date_shown = args.date_shown;
config.frontend.date_shown = matches!(date_shown.as_str(), "true");
}
if let Some(maximum_username_length) = args.max_username_length { if let Some(maximum_username_length) = args.max_username_length {
config.frontend.maximum_username_length = maximum_username_length; config.frontend.maximum_username_length = maximum_username_length;
} }
@ -78,6 +117,6 @@ pub fn merge_args_into_config(config: &mut CompleteConfig, args: Cli) {
} }
config.frontend.badges = args.badges; config.frontend.badges = args.badges;
if let Some(theme) = args.theme { if let Some(theme) = args.theme {
config.frontend.theme = Theme::from_str(theme.as_str()).unwrap(); config.frontend.theme = theme;
} }
} }

View File

@ -84,7 +84,7 @@ pub struct FrontendConfig {
/// The maximum length of a Twitch username. /// The maximum length of a Twitch username.
pub maximum_username_length: u16, pub maximum_username_length: u16,
/// Which side the username should be aligned to. /// Which side the username should be aligned to.
pub username_alignment: String, pub username_alignment: Alignment,
/// The color palette. /// The color palette.
pub palette: Palette, pub palette: Palette,
/// Show Title with time and channel. /// Show Title with time and channel.
@ -129,7 +129,7 @@ impl Default for FrontendConfig {
date_shown: true, date_shown: true,
date_format: "%a %b %e %T %Y".to_string(), date_format: "%a %b %e %T %Y".to_string(),
maximum_username_length: 26, maximum_username_length: 26,
username_alignment: "right".to_string(), username_alignment: Alignment::default(),
palette: Palette::default(), palette: Palette::default(),
title_shown: true, title_shown: true,
margin: 0, margin: 0,
@ -141,6 +141,32 @@ impl Default for FrontendConfig {
} }
} }
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum Alignment {
Left,
Center,
Right,
}
impl Default for Alignment {
fn default() -> Self {
Self::Right
}
}
impl FromStr for Alignment {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"left" => Ok(Self::Left),
"center" => Ok(Self::Center),
_ => Ok(Self::Right),
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
pub enum Palette { pub enum Palette {

View File

@ -176,7 +176,7 @@ impl Data {
let mut cell_vector = vec![ let mut cell_vector = vec![
Cell::from(align_text( Cell::from(align_text(
&self.author, &self.author,
frontend_config.username_alignment.as_str(), frontend_config.username_alignment,
frontend_config.maximum_username_length, frontend_config.maximum_username_length,
)) ))
.style(if self.system { .style(if self.system {

View File

@ -76,7 +76,7 @@ impl<'a, 'b, 'c, T: Backend> WindowAttributes<'a, 'b, 'c, T> {
pub fn draw_ui<T: Backend>(frame: &mut Frame<T>, app: &mut App, config: &CompleteConfig) { pub fn draw_ui<T: Backend>(frame: &mut Frame<T>, app: &mut App, config: &CompleteConfig) {
let username_column_title = align_text( let username_column_title = align_text(
"Username", "Username",
&config.frontend.username_alignment, config.frontend.username_alignment,
config.frontend.maximum_username_length, config.frontend.maximum_username_length,
); );

View File

@ -6,7 +6,9 @@ use tui::{style::Style, text::Span};
use unicode_segmentation::UnicodeSegmentation; use unicode_segmentation::UnicodeSegmentation;
use unicode_width::UnicodeWidthStr; use unicode_width::UnicodeWidthStr;
pub fn align_text(text: &str, alignment: &str, maximum_length: u16) -> String { use crate::handlers::config::Alignment;
pub fn align_text(text: &str, alignment: Alignment, maximum_length: u16) -> String {
assert!( assert!(
maximum_length >= 1, maximum_length >= 1,
"Parameter of 'maximum_length' cannot be below 1." "Parameter of 'maximum_length' cannot be below 1."
@ -20,13 +22,13 @@ pub fn align_text(text: &str, alignment: &str, maximum_length: u16) -> String {
} }
match alignment { match alignment {
"right" => format!("{}{}", " ".repeat(maximum_length as usize - dw), text), Alignment::Right => format!("{}{}", " ".repeat(maximum_length as usize - dw), text),
"center" => { Alignment::Center => {
let side_spaces = let side_spaces =
" ".repeat(((maximum_length / 2) - (((dw / 2) as f32).floor() as u16)) as usize); " ".repeat(((maximum_length / 2) - (((dw / 2) as f32).floor() as u16)) as usize);
format!("{}{}{}", side_spaces, text, side_spaces) format!("{}{}{}", side_spaces, text, side_spaces)
} }
_ => text.to_string(), Alignment::Left => text.to_string(),
} }
} }
@ -122,35 +124,35 @@ mod tests {
#[test] #[test]
#[should_panic(expected = "Parameter of 'maximum_length' cannot be below 1.")] #[should_panic(expected = "Parameter of 'maximum_length' cannot be below 1.")]
fn test_text_align_maximum_length() { fn test_text_align_maximum_length() {
align_text("", "left", 0); align_text("", Alignment::Left, 0);
} }
#[test] #[test]
fn test_text_align_left() { fn test_text_align_left() {
assert_eq!(align_text("a", "left", 10), "a".to_string()); assert_eq!(align_text("a", Alignment::Left, 10), "a".to_string());
assert_eq!(align_text("a", "left", 1), "a".to_string()); assert_eq!(align_text("a", Alignment::Left, 1), "a".to_string());
} }
#[test] #[test]
fn test_text_align_right() { fn test_text_align_right() {
assert_eq!( assert_eq!(
align_text("a", "right", 10), align_text("a", Alignment::Right, 10),
format!("{}{}", " ".repeat(9), "a") format!("{}{}", " ".repeat(9), "a")
); );
assert_eq!(align_text("a", "right", 1), "a".to_string()); assert_eq!(align_text("a", Alignment::Right, 1), "a".to_string());
assert_eq!(align_text("你好", "right", 5), " 你好"); assert_eq!(align_text("你好", Alignment::Right, 5), " 你好");
assert_eq!(align_text("👑123", "right", 6), " 👑123"); assert_eq!(align_text("👑123", Alignment::Right, 6), " 👑123");
} }
#[test] #[test]
fn test_text_align_center() { fn test_text_align_center() {
assert_eq!( assert_eq!(
align_text("a", "center", 11), align_text("a", Alignment::Center, 11),
format!("{}{}{}", " ".repeat(5), "a", " ".repeat(5)) format!("{}{}{}", " ".repeat(5), "a", " ".repeat(5))
); );
assert_eq!(align_text("a", "center", 1), "a".to_string()); assert_eq!(align_text("a", Alignment::Center, 1), "a".to_string());
assert_eq!(align_text("你好", "center", 6), " 你好 "); assert_eq!(align_text("你好", Alignment::Center, 6), " 你好 ");
assert_eq!(align_text("👑123", "center", 7), " 👑123 "); assert_eq!(align_text("👑123", Alignment::Center, 7), " 👑123 ");
} }
#[test] #[test]