Skip to content
This repository has been archived by the owner on Feb 14, 2023. It is now read-only.

Commit

Permalink
issue link, comments, tests, refactor
Browse files Browse the repository at this point in the history
add [this link](rust-lang/rustfmt#5320 (comment)) in a comment
  • Loading branch information
Rudxain committed Dec 23, 2022
1 parent ad0c591 commit 20e2ce8
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 78 deletions.
2 changes: 1 addition & 1 deletion .clippy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ array-size-threshold = 262144 #2^18
enum-variant-size-threshold = 128
too-many-arguments-threshold = 4
literal-representation-threshold = 16
too-many-lines-threshold = 64
too-many-lines-threshold = 69 # nice
trivial-copy-size-limit = 2
max-include-file-size = 262144
type-complexity-threshold = 64
Expand Down
41 changes: 32 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@
clippy::float_cmp_const
)]

use core::fmt;
use core::{fmt, str::FromStr};

#[allow(clippy::cast_precision_loss, clippy::float_arithmetic)]
/*const */
fn div_usize_as_f64(n: usize, d: usize) -> f64 {
n as f64 / d as f64
}
Expand Down Expand Up @@ -66,24 +67,25 @@ impl fmt::Display for CSSColor {
}
}

#[derive(Debug, PartialEq, Eq)]
pub enum GradientType {
Linear,
Radial,
//Conic
//Conic,
}

impl fmt::Display for GradientType {
// I wonder why Rust needs boilerplate here
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Linear => write!(f, "{}", LINE),
Self::Radial => write!(f, "{}", RAD),
}
}
}

impl core::str::FromStr for GradientType {
// I hope rustc optimizes both of these conversions into no-ops
impl FromStr for GradientType {
type Err = ();

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_ascii_lowercase().as_str() {
"l" | LINE => Ok(Self::Linear),
Expand All @@ -101,9 +103,9 @@ impl fmt::Display for ColorQuotes {
write!(f, "CSS colors must not contain quotes")
}
}

// to-do: use `core` when stable
//core
impl std::error::Error for ColorQuotes {}
// https://github.com/rust-lang/rustfmt/issues/5320#issuecomment-1363417363

#[must_use]
pub fn generate(t: &GradientType, colors: Vec<CSSColor>) -> String {
Expand All @@ -118,7 +120,7 @@ pub fn generate(t: &GradientType, colors: Vec<CSSColor>) -> String {
.into_iter()
.enumerate()
.map(|(i, c)| {
// `+ 0x10` is temporary. to-do: use a better estimation
// to-do: use a better estimation than `0x10`
let mut s = String::with_capacity(c.len() + 0x10);
let _ = write!(
s,
Expand All @@ -130,7 +132,7 @@ pub fn generate(t: &GradientType, colors: Vec<CSSColor>) -> String {
})
.collect();

// `+ 0x40` is temporary. to-do: use a better estimation
// to-do: use a better estimation than `0x40`
let mut out = String::with_capacity(body.len() + 0x40);

let _ = write!(
Expand Down Expand Up @@ -158,3 +160,24 @@ pub fn generate(t: &GradientType, colors: Vec<CSSColor>) -> String {

out
}

#[cfg(test)]
#[test]
fn identical_enum_str_gradient_conversion() {
assert_eq!(
GradientType::from_str(LINE).expect("").to_string(),
LINE.to_string()
);
assert_eq!(
GradientType::from_str(RAD).expect("").to_string(),
RAD.to_string()
);
assert_eq!(
GradientType::from_str(&GradientType::Linear.to_string()).expect(""),
GradientType::Linear
);
assert_eq!(
GradientType::from_str(&GradientType::Radial.to_string()).expect(""),
GradientType::Radial
);
}
129 changes: 61 additions & 68 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![warn(
unused,
future_incompatible,
clippy::unwrap_used,
clippy::exit,
clippy::cargo,
clippy::pedantic,
Expand All @@ -27,13 +28,14 @@
clippy::float_cmp,
clippy::float_cmp_const
)]

use std::{process::ExitCode, result, str::FromStr};
use core::str::FromStr;
use std::process::ExitCode;

#[allow(clippy::wildcard_imports)]
use sv3g::*;

fn css_color_from_str(s: &str) -> CSSColor {
#[allow(clippy::unwrap_used)]
CSSColor::new(s.to_string()).unwrap()
}

Expand All @@ -53,7 +55,7 @@ enum SubCmds {
Custom,
}

impl core::str::FromStr for SubCmds {
impl FromStr for SubCmds {
type Err = ();

fn from_str(input: &str) -> Result<Self, Self::Err> {
Expand Down Expand Up @@ -98,84 +100,75 @@ fn print_known(c: &[CSSColor]) {
println!("{}", generate(&GradientType::Linear, c.to_vec()));
}

#[allow(clippy::too_many_lines)] // lmao
fn main() -> ExitCode {
use std::env::args;
const NAME: &str = "sv3g";

let argv: Vec<String> = args().skip(1).collect();
if argv.is_empty() {
if args().count() < 2 {
eprintln!("No arguments provided. Run `{} help` for more info", NAME);
return ExitCode::SUCCESS;
}

let subcmd = SubCmds::from_str(argv[0].as_str());
if subcmd == Err(()) {
eprintln!(
"Unrecognized sub-command:\n{}\nRun `{} help` to get list of valid ones",
argv[0], NAME
);
return ExitCode::FAILURE;
};

// is there a better way?
let mut argv = argv;
argv.remove(0);
argv.shrink_to_fit();
let argv = argv;
let arg1: String = args().skip(1).take(1).collect();

// this feels redundant
let subcmd = subcmd.unwrap();

match subcmd {
SubCmds::Help => {
println!(
"\
usage: {} <subcommand> [colors...]\n\
help | HELP | man | /? | ❔ | ❓ | ℹ️ | ℹ : print this text\n\
wb | WB: grayscale\n\
rainbow | 🌈: RYGCBM\n\
sky : like a skybox\n\
mint | Mint : Linux Mint\n\
fire | 🔥 : is it a candle?\n\
custom : to specify arbitrary colors\
",
NAME
);
}
SubCmds::Wb(c) | SubCmds::Mint(c) => {
print_known(&c);
}
SubCmds::Rainbow(c) => {
print_known(&c);
}
SubCmds::Sky(c) => {
print_known(&c);
}
SubCmds::Fire(c) => {
print_known(&c);
}
SubCmds::Custom => {
let colors: Vec<_> = argv.into_iter().map(CSSColor::new).collect();
if let Ok(subcmd) = SubCmds::from_str(arg1.as_str()) {
match subcmd {
SubCmds::Help => {
println!(
"\
usage: {} <subcommand> [colors...]\n\
help | HELP | man | /? | ❔ | ❓ | ℹ️ | ℹ : print this text\n\
wb | WB: grayscale\n\
rainbow | 🌈: RYGCBM\n\
sky : like a skybox\n\
mint | Mint : Linux Mint\n\
fire | 🔥 : is it a candle?\n\
custom : to specify arbitrary colors\
",
NAME
);
}
SubCmds::Wb(c) | SubCmds::Mint(c) => {
print_known(&c);
}
SubCmds::Rainbow(c) => {
print_known(&c);
}
SubCmds::Sky(c) => {
print_known(&c);
}
SubCmds::Fire(c) => {
print_known(&c);
}
SubCmds::Custom => {
let colors: Vec<_> = args().skip(2).into_iter().map(CSSColor::new).collect();

for r in &colors {
match r {
Ok(_) => continue,
Err(e) => {
eprintln!("{}", e);
return ExitCode::FAILURE;
for r in &colors {
match r {
Ok(_) => continue,
Err(e) => {
eprintln!("{}", e);
return ExitCode::FAILURE;
}
}
}
println!(
"{}",
generate(
&GradientType::Linear,
colors
.into_iter()
.map(core::result::Result::unwrap)
.collect()
)
);
}
println!(
"{}",
generate(
&GradientType::Linear,
colors.into_iter().map(result::Result::unwrap).collect()
)
);
}
return ExitCode::SUCCESS;
}

ExitCode::SUCCESS
eprintln!(
"Unrecognized sub-command:\n{}\nRun `{} help` to get list of valid ones",
arg1, NAME
);
ExitCode::FAILURE
}

0 comments on commit 20e2ce8

Please sign in to comment.