10 Commits

16 changed files with 1450 additions and 115 deletions

12
README.md Normal file
View File

@@ -0,0 +1,12 @@
# Developer tools
My personal set of tools to ease and speed up my development experience.
1. `colorizer`: color model converter.
## Compiling
To compile the program on your local environment simply run:
- `$ cargo build --release`

1
api-faker/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

7
api-faker/Cargo.lock generated Normal file
View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "api-faker"
version = "0.1.0"

6
api-faker/Cargo.toml Normal file
View File

@@ -0,0 +1,6 @@
[package]
name = "api-faker"
version = "0.1.0"
edition = "2024"
[dependencies]

View File

3
api-faker/src/main.rs Normal file
View File

@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

732
colorizer/Cargo.lock generated
View File

@@ -3,46 +3,281 @@
version = 4 version = 4
[[package]] [[package]]
name = "block" name = "adler2"
version = "0.1.6" version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]] [[package]]
name = "clipboard" name = "aho-corasick"
version = "0.5.0" version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25a904646c0340239dcf7c51677b33928bf24fdf424b79a57909c0109075b2e7" checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [ dependencies = [
"clipboard-win", "memchr",
"objc",
"objc-foundation",
"objc_id",
"x11-clipboard",
] ]
[[package]] [[package]]
name = "clipboard-win" name = "arboard"
version = "2.2.0" version = "3.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3a093d6fed558e5fe24c3dfc85a68bb68f1c824f440d3ba5aca189e2998786b" checksum = "55f533f8e0af236ffe5eb979b99381df3258853f00ba2e44b6e1955292c75227"
dependencies = [ dependencies = [
"winapi", "clipboard-win",
"image",
"log",
"objc2",
"objc2-app-kit",
"objc2-core-foundation",
"objc2-core-graphics",
"objc2-foundation",
"parking_lot",
"percent-encoding",
"windows-sys 0.59.0",
"x11rb",
]
[[package]]
name = "autocfg"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
[[package]]
name = "bytemuck"
version = "1.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "byteorder-lite"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
[[package]]
name = "cfg-if"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
[[package]]
name = "clipboard-win"
version = "5.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4"
dependencies = [
"error-code",
]
[[package]]
name = "colored"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e"
dependencies = [
"windows-sys 0.59.0",
] ]
[[package]] [[package]]
name = "colorizer" name = "colorizer"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"clipboard", "arboard",
"colored",
"inquire",
"regex",
] ]
[[package]]
name = "crc32fast"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
dependencies = [
"cfg-if",
]
[[package]]
name = "crossterm"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67"
dependencies = [
"bitflags 1.3.2",
"crossterm_winapi",
"libc",
"mio",
"parking_lot",
"signal-hook",
"signal-hook-mio",
"winapi",
]
[[package]]
name = "crossterm_winapi"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
dependencies = [
"winapi",
]
[[package]]
name = "dispatch2"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec"
dependencies = [
"bitflags 2.9.1",
"objc2",
]
[[package]]
name = "dyn-clone"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
[[package]]
name = "errno"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
dependencies = [
"libc",
"windows-sys 0.59.0",
]
[[package]]
name = "error-code"
version = "3.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59"
[[package]]
name = "fdeflate"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c"
dependencies = [
"simd-adler32",
]
[[package]]
name = "flate2"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "fuzzy-matcher"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94"
dependencies = [
"thread_local",
]
[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
dependencies = [
"byteorder",
]
[[package]]
name = "gethostname"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818"
dependencies = [
"libc",
"windows-targets 0.48.5",
]
[[package]]
name = "image"
version = "0.25.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a"
dependencies = [
"bytemuck",
"byteorder-lite",
"num-traits",
"png",
"tiff",
]
[[package]]
name = "inquire"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fddf93031af70e75410a2511ec04d49e758ed2f26dad3404a934e0fb45cc12a"
dependencies = [
"bitflags 2.9.1",
"crossterm",
"dyn-clone",
"fuzzy-matcher",
"fxhash",
"newline-converter",
"once_cell",
"unicode-segmentation",
"unicode-width",
]
[[package]]
name = "jpeg-decoder"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00810f1d8b74be64b13dbf3db89ac67740615d6c891f0e7b6179326533011a07"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.174" version = "0.2.174"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
[[package]]
name = "linux-raw-sys"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "lock_api"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.27" version = "0.4.27"
@@ -50,42 +285,314 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]] [[package]]
name = "malloc_buf" name = "memchr"
version = "0.0.6" version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
[[package]]
name = "miniz_oxide"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
dependencies = [
"adler2",
"simd-adler32",
]
[[package]]
name = "mio"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
dependencies = [
"libc",
"log",
"wasi",
"windows-sys 0.48.0",
]
[[package]]
name = "newline-converter"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47b6b097ecb1cbfed438542d16e84fd7ad9b0c76c8a65b7f9039212a3d14dc7f"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "objc2"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "561f357ba7f3a2a61563a186a163d0a3a5247e1089524a3981d49adb775078bc"
dependencies = [
"objc2-encode",
]
[[package]]
name = "objc2-app-kit"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc"
dependencies = [
"bitflags 2.9.1",
"objc2",
"objc2-core-graphics",
"objc2-foundation",
]
[[package]]
name = "objc2-core-foundation"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166"
dependencies = [
"bitflags 2.9.1",
"dispatch2",
"objc2",
]
[[package]]
name = "objc2-core-graphics"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4"
dependencies = [
"bitflags 2.9.1",
"dispatch2",
"objc2",
"objc2-core-foundation",
"objc2-io-surface",
]
[[package]]
name = "objc2-encode"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33"
[[package]]
name = "objc2-foundation"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c"
dependencies = [
"bitflags 2.9.1",
"objc2",
"objc2-core-foundation",
]
[[package]]
name = "objc2-io-surface"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c"
dependencies = [
"bitflags 2.9.1",
"objc2",
"objc2-core-foundation",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "parking_lot"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-targets 0.52.6",
]
[[package]]
name = "percent-encoding"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "png"
version = "0.17.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526"
dependencies = [
"bitflags 1.3.2",
"crc32fast",
"fdeflate",
"flate2",
"miniz_oxide",
]
[[package]]
name = "redox_syscall"
version = "0.5.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77"
dependencies = [
"bitflags 2.9.1",
]
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "rustix"
version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [
"bitflags 2.9.1",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.59.0",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "signal-hook"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2"
dependencies = [
"libc",
"signal-hook-registry",
]
[[package]]
name = "signal-hook-mio"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd"
dependencies = [
"libc",
"mio",
"signal-hook",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b"
dependencies = [ dependencies = [
"libc", "libc",
] ]
[[package]] [[package]]
name = "objc" name = "simd-adler32"
version = "0.2.7" version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
[[package]]
name = "smallvec"
version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "thread_local"
version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
dependencies = [ dependencies = [
"malloc_buf", "cfg-if",
] ]
[[package]] [[package]]
name = "objc-foundation" name = "tiff"
version = "0.1.1" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e"
dependencies = [ dependencies = [
"block", "flate2",
"objc", "jpeg-decoder",
"objc_id", "weezl",
] ]
[[package]] [[package]]
name = "objc_id" name = "unicode-segmentation"
version = "0.1.1" version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
dependencies = [
"objc", [[package]]
] name = "unicode-width"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "weezl"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3"
[[package]] [[package]]
name = "winapi" name = "winapi"
@@ -110,20 +617,157 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "x11-clipboard" name = "windows-sys"
version = "0.3.3" version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89bd49c06c9eb5d98e6ba6536cf64ac9f7ee3a009b2f53996d405b3944f6bcea" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [ dependencies = [
"xcb", "windows-targets 0.48.5",
] ]
[[package]] [[package]]
name = "xcb" name = "windows-sys"
version = "0.8.2" version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e917a3f24142e9ff8be2414e36c649d47d6cc2ba81f16201cdef96e533e02de" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [ dependencies = [
"libc", "windows-targets 0.52.6",
"log",
] ]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_i686_gnullvm",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "x11rb"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12"
dependencies = [
"gethostname",
"rustix",
"x11rb-protocol",
]
[[package]]
name = "x11rb-protocol"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d"

View File

@@ -4,4 +4,7 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
clipboard = "0.5.0" arboard = "3.6.0"
colored = "3.0.0"
inquire = "0.7.5"
regex = "1.11.1"

10
colorizer/README.md Normal file
View File

@@ -0,0 +1,10 @@
# Colorizer
Simple CLI color parser. Reads the color to be parsed either from the clipboard, from and input argument or directly from the user keyboard manual input.
## Arguments
The program allows one of these 2 arguments:
- `--clipboard` / `-c` : read from clipboard first
- `--input <String>` / `-i <String>` : dont read from clipboard nor input, simply try parsing the input

View File

@@ -1,4 +1,7 @@
use std::fmt::Display;
use crate::color::{ColorHue, HSL, Percentage, RGB}; use crate::color::{ColorHue, HSL, Percentage, RGB};
use regex::Regex;
impl HSL { impl HSL {
pub fn new(h: u16, s: u8, l: u8) -> Self { pub fn new(h: u16, s: u8, l: u8) -> Self {
@@ -10,36 +13,42 @@ impl HSL {
} }
} }
fn min_of_float_vec(vector: Vec<f32>) -> Option<f32> { impl Display for HSL {
let mut min: Option<f32> = None; fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "hsl({}, {}%, {}%)", self.0, self.1, self.2)
for element in vector.iter() {
if let Some(value) = min {
if element < &value {
min = Some(*element)
}
} else {
min = Some(*element);
}
} }
min
} }
fn max_of_float_vec(vector: Vec<f32>) -> Option<f32> { impl PartialEq for HSL {
let mut max: Option<f32> = None; fn eq(&self, other: &Self) -> bool {
self.0 == other.0 && self.1 == other.1 && self.2 == other.2
for element in vector.iter() {
if let Some(value) = max {
if element > &value {
max = Some(*element)
}
} else {
max = Some(*element);
}
} }
max fn ne(&self, other: &Self) -> bool {
self.0 != other.0 || self.1 != other.1 || self.2 != other.2
}
}
// TODO: manage error
impl From<String> for HSL {
fn from(value: String) -> Self {
let regex = Regex::new(r"hsl\(([0-9]+),([0-9]+),([0-9 ]+)\)").unwrap();
let numbers = value.replace(" ", "").replace("%", "");
let result = regex.captures(&numbers);
match result {
Some(value_list) => {
// Numeric
let h: u16 = value_list[1].parse::<u16>().unwrap();
let s: u8 = value_list[2].parse::<u8>().unwrap();
let l: u8 = value_list[3].parse::<u8>().unwrap();
return Self::new(h, s, l);
}
None => (),
}
Self::new(0, 0, 0)
}
} }
impl From<RGB> for HSL { impl From<RGB> for HSL {
@@ -48,36 +57,38 @@ impl From<RGB> for HSL {
let g = value.1.to_f32() / 255.0; let g = value.1.to_f32() / 255.0;
let b = value.2.to_f32() / 255.0; let b = value.2.to_f32() / 255.0;
let min: f32 = min_of_float_vec(vec![r, g, b]).unwrap(); let min: f32 = r.min(g.min(b));
let max: f32 = max_of_float_vec(vec![r, g, b]).unwrap(); let max: f32 = r.max(g.max(b));
// Luminance let h;
let l = ((min + max) / 2.0).round(); let s;
// Luminance set
let l = (min + max) / 2.0;
// Saturation if max == min {
let s: f32;
if r == g && g == b {
s = 0.0; s = 0.0;
h = 0.0;
} else { } else {
// Saturation set
if l <= 0.5 { if l <= 0.5 {
s = (max - min) / (max + min); s = (max - min) / (max + min);
} else { } else {
s = (max - min) / (2.0 - max - min); s = (max - min) / (2.0 - max - min);
} }
}
// Hue // Hue set
let h: f32; if max == r {
if max == r { let temp = if g < b { 6.0 } else { 0.0 };
h = (g - b) / (max - min); h = (g - b) / (max - min) + temp;
} else if max == g { } else if max == g {
h = 2.0 + (b - r) / (max - min); h = (b - r) / (max - min) + 2.0;
} else { } else {
h = 4.0 + (r - g) / (max - min); h = (r - g) / (max - min) + 4.0;
}
} }
HSL::new( HSL::new(
(h * 60.0).round() as u16, (h / 6.0 * 360.0).round() as u16,
(s * 100.0).round() as u8, (s * 100.0).round() as u8,
(l * 100.0).round() as u8, (l * 100.0).round() as u8,
) )

View File

@@ -0,0 +1,92 @@
use regex::Regex;
use std::fmt::Display;
use crate::color::{ColorHue, HSV, Percentage, RGB};
impl HSV {
pub fn new(h: u16, s: u8, v: u8) -> Self {
Self(
ColorHue::new(h as i16),
Percentage::new(s as i16),
Percentage::new(v as i16),
)
}
}
impl Display for HSV {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "hsv({}, {}%, {}%)", self.0, self.1, self.2)
}
}
impl PartialEq for HSV {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0 && self.1 == other.1 && self.2 == other.2
}
fn ne(&self, other: &Self) -> bool {
self.0 != other.0 || self.1 != other.1 || self.2 != other.2
}
}
// TODO: manage error
impl From<String> for HSV {
fn from(value: String) -> Self {
let regex = Regex::new(r"hsv\(([0-9]+),([0-9]+),([0-9 ]+)\)").unwrap();
let numbers = value.replace(" ", "").replace("%", "");
let result = regex.captures(&numbers);
match result {
Some(value_list) => {
// Numeric
let h: u16 = value_list[1].parse::<u16>().unwrap();
let s: u8 = value_list[2].parse::<u8>().unwrap();
let v: u8 = value_list[3].parse::<u8>().unwrap();
return Self::new(h, s, v);
}
None => (),
}
Self::new(0, 0, 0)
}
}
impl From<RGB> for HSV {
fn from(color: RGB) -> Self {
let r = color.0.to_f32() / 255.0;
let g = color.1.to_f32() / 255.0;
let b = color.2.to_f32() / 255.0;
let min: f32 = r.min(g.min(b));
let max: f32 = r.max(g.max(b));
let v = max;
if min == max {
return Self::new(0, 0, v as u8);
}
let s = (max - min) / max;
let dif = max - min;
let rc = (max - r) / dif;
let gc = (max - g) / dif;
let bc = (max - b) / dif;
let mut h: f32;
if r == max {
h = bc - gc;
} else if g == max {
h = 2.0 + rc - bc;
} else {
h = 4.0 + gc - rc;
}
h = (h / 6.0).rem_euclid(1.0);
Self::new(
(h * 360.0).round() as u16,
(s * 100.0).round() as u8,
(v * 100.0).round() as u8,
)
}
}

View File

@@ -3,23 +3,74 @@
mod test; mod test;
pub mod hsl; pub mod hsl;
pub mod hsv;
pub mod rgb; pub mod rgb;
use std::fmt::UpperHex;
use regex::Regex;
use crate::core::ranged::RangedInt; use crate::core::ranged::RangedInt;
pub type ColorIntensity = RangedInt<0, 255>; pub type ColorIntensity = RangedInt<0, 255>;
pub type ColorHue = RangedInt<0, 360>; pub type ColorHue = RangedInt<0, 360>;
pub type Percentage = RangedInt<0, 100>; pub type Percentage = RangedInt<0, 100>;
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct RGB(ColorIntensity, ColorIntensity, ColorIntensity); pub struct RGB(pub ColorIntensity, pub ColorIntensity, pub ColorIntensity);
#[derive(Debug, Clone)]
pub struct HSL(ColorHue, Percentage, Percentage); pub struct HSL(ColorHue, Percentage, Percentage);
// pub struct HSV(ColorHue, Percentage, Percentage); #[derive(Debug, Clone)]
#[derive(Debug)] pub struct HSV(ColorHue, Percentage, Percentage);
#[derive(Debug, Clone)]
pub struct Color(RGB); pub struct Color(RGB);
impl Color { impl Color {
pub fn format(&self) -> String { pub fn try_parse(input: String) -> Result<Color, ()> {
format!("{:?}", self.0) let input = input.replace(" ", "").to_lowercase();
// TODO: clean all of this to manage errors on a clean and simple way
// - Move down to custom trait that returns a Result
let hex_regex = Regex::new(r".*(#[a-fA-F0-9]{3,6}).*").unwrap();
let rgb_regex =
Regex::new(r".*(rgb\([ ]*[0-9]+[ ]*,[ ]*[0-9]+[ ]*,[ ]*[0-9 ]+[ ]*\)).*").unwrap();
let hsl_regex =
Regex::new(r".*(hsl\([ ]*[0-9]+[ ]*,[0-9]+[ ]*[%]*[ ]*,[0-9 ]+[ ]*[%]*[ ]*\)).*")
.unwrap();
let hsv_regex =
Regex::new(r".*(hsv\([ ]*[0-9]+[ ]*,[0-9]+[ ]*[%]*[ ]*,[0-9 ]+[ ]*[%]*[ ]*\)).*")
.unwrap();
let hex_result = hex_regex.captures(&input);
match hex_result {
Some(color) => return Ok(Color::from(RGB::from(color[1].to_string()))),
None => (),
}
let rgb_result = rgb_regex.captures(&input);
match rgb_result {
Some(color) => return Ok(Color::from(RGB::from(color[1].to_string()))),
None => (),
}
let hsl_result = hsl_regex.captures(&input);
match hsl_result {
Some(color) => return Ok(Color::from(HSL::from(color[1].to_string()))),
None => (),
}
let hsv_result = hsv_regex.captures(&input);
match hsv_result {
Some(color) => return Ok(Color::from(HSV::from(color[1].to_string()))),
None => (),
}
Err(())
}
}
impl UpperHex for Color {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:X}", self.0)
} }
} }
@@ -44,3 +95,27 @@ impl From<HSL> for Color {
Color(RGB::from(color)) Color(RGB::from(color))
} }
} }
impl From<HSV> for Color {
fn from(color: HSV) -> Self {
Color(RGB::from(color))
}
}
impl Into<RGB> for Color {
fn into(self) -> RGB {
self.0
}
}
impl Into<HSL> for Color {
fn into(self) -> HSL {
HSL::from(self.0)
}
}
impl Into<HSV> for Color {
fn into(self) -> HSV {
HSV::from(self.0)
}
}

View File

@@ -1,5 +1,8 @@
use regex::Regex;
use std::fmt::{Display, UpperHex};
use crate::{ use crate::{
color::{ColorIntensity, HSL, RGB}, color::{ColorIntensity, HSL, HSV, RGB},
core::ranged::BaseNumber, core::ranged::BaseNumber,
}; };
@@ -11,6 +14,47 @@ impl RGB {
ColorIntensity::new(b as BaseNumber), ColorIntensity::new(b as BaseNumber),
) )
} }
pub fn to_u8_tuple(self) -> (u8, u8, u8) {
(
self.0.to_f32() as u8,
self.1.to_f32() as u8,
self.2.to_f32() as u8,
)
}
}
// TODO: manage error
impl From<String> for RGB {
fn from(value: String) -> Self {
let regex = Regex::new(r"rgb\(([0-9]+),([0-9]+),([0-9 ]+)\)").unwrap();
let mut numbers = value.replace(" ", "");
let result = regex.captures(&numbers);
match result {
Some(value_list) => {
// Numeric
let r: u8 = value_list[1].parse::<u8>().unwrap();
let g: u8 = value_list[2].parse::<u8>().unwrap();
let b: u8 = value_list[3].parse::<u8>().unwrap();
return Self::new(r, g, b);
}
None => {
// Hex
if numbers.len() == 7 {
numbers.remove(0);
let hex = numbers.split_at(2);
let r = u8::from_str_radix(hex.0, 16).unwrap();
let hex = hex.1.split_at(2);
let g = u8::from_str_radix(hex.0, 16).unwrap();
let b = u8::from_str_radix(hex.1, 16).unwrap();
return Self::new(r, g, b);
}
}
}
Self::new(0, 0, 0)
}
} }
impl PartialEq for RGB { impl PartialEq for RGB {
@@ -23,6 +67,18 @@ impl PartialEq for RGB {
} }
} }
impl Display for RGB {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "rgb({}, {}, {})", self.0, self.1, self.2)
}
}
impl UpperHex for RGB {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "#{:0>2X}{:0>2X}{:0>2X}", self.0, self.1, self.2)
}
}
fn hue_to_rgb(p: f32, q: f32, mut t: f32) -> f32 { fn hue_to_rgb(p: f32, q: f32, mut t: f32) -> f32 {
if t < 0.0 { if t < 0.0 {
t += 1.0; t += 1.0;
@@ -78,3 +134,66 @@ impl From<HSL> for RGB {
) )
} }
} }
impl From<HSV> for RGB {
fn from(color: HSV) -> Self {
let h = color.0.to_f32() / 360.0;
let s = color.1.to_f32() / 100.0;
let v = color.2.to_f32() / 100.0;
if s == 0.0 {
let grey = (v * 255.0) as u8;
return Self::new(grey, grey, grey);
}
let i = (h * 6.0) as u8;
let f = (h * 6.0) - i as f32;
let p = v * (1.0 - s);
let q = v * (1.0 - s * f);
let t = v * (1.0 - s * (1.0 - f));
let i = i % 6;
if i == 0 {
return Self::new(
(v * 255.0).round() as u8,
(t * 255.0).round() as u8,
(p * 255.0).round() as u8,
);
}
if i == 1 {
return Self::new(
(q * 255.0).round() as u8,
(v * 255.0).round() as u8,
(p * 255.0).round() as u8,
);
}
if i == 2 {
return Self::new(
(p * 255.0).round() as u8,
(v * 255.0).round() as u8,
(t * 255.0).round() as u8,
);
}
if i == 3 {
return Self::new(
(p * 255.0).round() as u8,
(q * 255.0).round() as u8,
(v * 255.0).round() as u8,
);
}
if i == 4 {
return Self::new(
(t * 255.0).round() as u8,
(p * 255.0).round() as u8,
(v * 255.0).round() as u8,
);
}
return Self::new(
(v * 255.0).round() as u8,
(p * 255.0).round() as u8,
(q * 255.0).round() as u8,
);
}
}

View File

@@ -1,16 +1,9 @@
#[cfg(test)] #[cfg(test)]
pub mod tests { pub mod tests {
use crate::color::{Color, HSL, RGB}; use crate::color::{Color, HSL, HSV, RGB};
#[test] #[test]
fn test_conversion() { fn test_color_initialization() {
let hsl_color = Color::from(HSL::new(193, 67, 28));
let rgb_color = Color::from(RGB::from(HSL::new(193, 67, 28)));
assert_eq!(hsl_color, rgb_color);
}
#[test]
fn test_hsl_variants() {
let red_hsl = Color::from(HSL::new(0, 100, 50)); let red_hsl = Color::from(HSL::new(0, 100, 50));
let red_rgb = Color::from(RGB::new(255, 0, 0)); let red_rgb = Color::from(RGB::new(255, 0, 0));
assert_eq!(red_hsl, red_rgb); assert_eq!(red_hsl, red_rgb);
@@ -23,4 +16,262 @@ pub mod tests {
let blue_rgb = Color::from(RGB::new(0, 0, 255)); let blue_rgb = Color::from(RGB::new(0, 0, 255));
assert_eq!(blue_hsl, blue_rgb); assert_eq!(blue_hsl, blue_rgb);
} }
#[test]
fn test_conversion() {
let hsl_color = Color::from(HSL::new(193, 67, 28));
let rgb_color = Color::from(RGB::from(HSL::new(193, 67, 28)));
assert_eq!(hsl_color, rgb_color);
}
#[test]
fn test_rgb_to_hsl() {
let red_rgb = RGB::new(255, 0, 0);
let red_hsl = HSL::new(0, 100, 50);
assert_eq!(HSL::from(red_rgb), red_hsl);
let green_rgb = RGB::new(0, 255, 0);
let green_hsl = HSL::new(120, 100, 50);
assert_eq!(HSL::from(green_rgb), green_hsl);
let blue_rgb = RGB::new(0, 0, 255);
let blue_hsl = HSL::new(240, 100, 50);
assert_eq!(HSL::from(blue_rgb), blue_hsl);
// Variant colors
let pink_rgb = RGB::new(255, 175, 204);
let pink_hsl = HSL::new(338, 100, 84);
assert_eq!(HSL::from(pink_rgb), pink_hsl);
let orange_rgb = RGB::new(251, 133, 0);
let orange_hsl = HSL::new(32, 100, 49);
assert_eq!(HSL::from(orange_rgb), orange_hsl);
let yellow_rgb = RGB::new(255, 214, 10);
let yellow_hsl = HSL::new(50, 100, 52);
assert_eq!(HSL::from(yellow_rgb), yellow_hsl);
let purple_rgb = RGB::new(123, 44, 191);
let purple_hsl = HSL::new(272, 63, 46);
assert_eq!(HSL::from(purple_rgb), purple_hsl);
}
#[test]
fn test_hsl_to_rgb() {
let red_rgb = RGB::new(255, 0, 0);
let red_hsl = HSL::new(0, 100, 50);
assert_eq!(red_rgb, RGB::from(red_hsl));
let green_rgb = RGB::new(0, 255, 0);
let green_hsl = HSL::new(120, 100, 50);
assert_eq!(green_rgb, RGB::from(green_hsl));
let blue_rgb = RGB::new(0, 0, 255);
let blue_hsl = HSL::new(240, 100, 50);
assert_eq!(blue_rgb, RGB::from(blue_hsl));
// Variant colors
let pink_rgb = RGB::new(255, 173, 203);
let pink_hsl = HSL::new(338, 100, 84);
assert_eq!(pink_rgb, RGB::from(pink_hsl));
let orange_rgb = RGB::new(250, 133, 0);
let orange_hsl = HSL::new(32, 100, 49);
assert_eq!(orange_rgb, RGB::from(orange_hsl));
let yellow_rgb = RGB::new(255, 214, 10);
let yellow_hsl = HSL::new(50, 100, 52);
assert_eq!(yellow_rgb, RGB::from(yellow_hsl));
let purple_rgb = RGB::new(122, 43, 191);
let purple_hsl = HSL::new(272, 63, 46);
assert_eq!(purple_rgb, RGB::from(purple_hsl));
}
#[test]
fn test_basic_hex_convertion() {
let red_color = Color::from(RGB::new(255, 0, 0));
let green_color = Color::from(RGB::new(0, 255, 0));
let blue_color = Color::from(RGB::new(0, 0, 255));
assert_eq!(format!("{:X}", red_color), "#FF0000");
assert_eq!(format!("{:X}", green_color), "#00FF00");
assert_eq!(format!("{:X}", blue_color), "#0000FF");
}
#[test]
fn test_complex_hex_convertion() {
let color = Color::from(RGB::new(255, 183, 3));
assert_eq!(format!("{:X}", color), "#FFB703");
let color = Color::from(RGB::new(88, 129, 87));
assert_eq!(format!("{:X}", color), "#588157");
let color = Color::from(RGB::new(251, 133, 0));
assert_eq!(format!("{:X}", color), "#FB8500");
let color = Color::from(RGB::new(131, 56, 236));
assert_eq!(format!("{:X}", color), "#8338EC");
let color = Color::from(RGB::new(157, 129, 137));
assert_eq!(format!("{:X}", color), "#9D8189");
}
#[test]
fn test_hsv_from_rgb() {
// Base colors
let color = RGB::new(255, 0, 0);
assert_eq!(HSV::from(color), HSV::new(0, 100, 100));
let color = RGB::new(0, 255, 0);
assert_eq!(HSV::from(color), HSV::new(120, 100, 100));
let color = RGB::new(0, 0, 255);
assert_eq!(HSV::from(color), HSV::new(240, 100, 100));
// Complex colors
let color = RGB::new(20, 240, 100);
assert_eq!(HSV::from(color), HSV::new(142, 92, 94));
let color = RGB::new(220, 10, 50);
assert_eq!(HSV::from(color), HSV::new(349, 95, 86));
}
#[test]
fn test_rgb_from_hsv() {
// Base colors
let color = HSV::new(0, 100, 100);
assert_eq!(RGB::from(color), RGB::new(255, 0, 0));
let color = HSV::new(120, 100, 100);
assert_eq!(RGB::from(color), RGB::new(0, 255, 0));
let color = HSV::new(240, 100, 100);
assert_eq!(RGB::from(color), RGB::new(0, 0, 255));
// Complex colors
let color = HSV::new(349, 95, 86);
assert_eq!(RGB::from(color), RGB::new(219, 11, 49));
let color = HSV::new(142, 92, 94);
assert_eq!(RGB::from(color), RGB::new(19, 240, 100));
}
#[test]
fn test_rgb_string_parse() {
// Base colors
// HEX
let color = "#FF0000";
assert_eq!(RGB::from(color.to_string()), RGB::new(255, 0, 0));
let color = "#00FF00";
assert_eq!(RGB::from(color.to_string()), RGB::new(0, 255, 0));
let color = "#0000FF";
assert_eq!(RGB::from(color.to_string()), RGB::new(0, 0, 255));
// RGB
let color = "rgb(255 ,0,0)";
assert_eq!(RGB::from(color.to_string()), RGB::new(255, 0, 0));
let color = "rgb(0,255, 0)";
assert_eq!(RGB::from(color.to_string()), RGB::new(0, 255, 0));
let color = "rgb(0 , 0, 255)";
assert_eq!(RGB::from(color.to_string()), RGB::new(0, 0, 255));
// Complex colors
// HEX
let color = "#Ffb703";
assert_eq!(RGB::from(color.to_string()), RGB::new(255, 183, 3));
let color = "#588157";
assert_eq!(RGB::from(color.to_string()), RGB::new(88, 129, 87));
let color = "#fB8500";
assert_eq!(RGB::from(color.to_string()), RGB::new(251, 133, 0));
let color = "#8338eC";
assert_eq!(RGB::from(color.to_string()), RGB::new(131, 56, 236));
let color = "#9D8189";
assert_eq!(RGB::from(color.to_string()), RGB::new(157, 129, 137));
// RGB
let color = "rgb(255, 183, 3)";
assert_eq!(RGB::from(color.to_string()), RGB::new(255, 183, 3));
let color = "rgb(88, 129, 87)";
assert_eq!(RGB::from(color.to_string()), RGB::new(88, 129, 87));
let color = "rgb(251, 133, 0)";
assert_eq!(RGB::from(color.to_string()), RGB::new(251, 133, 0));
let color = "rgb(131, 56, 236)";
assert_eq!(RGB::from(color.to_string()), RGB::new(131, 56, 236));
let color = "rgb(157, 129, 137)";
assert_eq!(RGB::from(color.to_string()), RGB::new(157, 129, 137));
}
#[test]
fn test_hsl_string_parse() {
// Base colors
let color = "hsl(0, 100, 50)";
assert_eq!(HSL::from(color.to_string()), HSL::new(0, 100, 50));
let color = "hsl(120, 100, 50)";
assert_eq!(HSL::from(color.to_string()), HSL::new(120, 100, 50));
let color = "hsl(240, 100, 50)";
assert_eq!(HSL::from(color.to_string()), HSL::new(240, 100, 50));
// Complex colors
let color = "hsl(255 , 83, 3)";
assert_eq!(HSL::from(color.to_string()), HSL::new(255, 83, 3));
let color = "hsl(88 , 29,87)";
assert_eq!(HSL::from(color.to_string()), HSL::new(88, 29, 87));
let color = "hsl(251,33,0)";
assert_eq!(HSL::from(color.to_string()), HSL::new(251, 33, 0));
let color = "hsl(131,56,36)";
assert_eq!(HSL::from(color.to_string()), HSL::new(131, 56, 36));
let color = "hsl(157,29, 37 )";
assert_eq!(HSL::from(color.to_string()), HSL::new(157, 29, 37));
}
#[test]
fn test_hsv_string_parse() {
// Base colors
let color = "hsv(0, 100, 50)";
assert_eq!(HSV::from(color.to_string()), HSV::new(0, 100, 50));
let color = "hsv(120, 100, 50)";
assert_eq!(HSV::from(color.to_string()), HSV::new(120, 100, 50));
let color = "hsv(240, 100, 50)";
assert_eq!(HSV::from(color.to_string()), HSV::new(240, 100, 50));
// Complex colors
let color = "hsv(255 , 83, 3)";
assert_eq!(HSV::from(color.to_string()), HSV::new(255, 83, 3));
let color = "hsv(88 , 29,87)";
assert_eq!(HSV::from(color.to_string()), HSV::new(88, 29, 87));
let color = "hsv(251,33,0)";
assert_eq!(HSV::from(color.to_string()), HSV::new(251, 33, 0));
let color = "hsv(131,56,36)";
assert_eq!(HSV::from(color.to_string()), HSV::new(131, 56, 36));
let color = "hsv(157,29, 37 )";
assert_eq!(HSV::from(color.to_string()), HSV::new(157, 29, 37));
}
#[test]
fn test_color_string_parse() {
let input = "test1hsv(255 , 83, 3)test2";
let result = Color::try_parse(input.to_string());
assert_eq!(result, Ok(Color::from(HSV::from(input.to_string()))));
let input = "test1hsj(255 , 83, 3)test2";
let result = Color::try_parse(input.to_string());
assert_eq!(result, Err(()));
let input = "test1hsl(25a , 83, 3)test2";
let result = Color::try_parse(input.to_string());
assert_eq!(result, Err(()));
let input = "#afj";
let result = Color::try_parse(input.to_string());
assert_eq!(result, Err(()));
let input = "p#test2#010203j";
let result = Color::try_parse(input.to_string());
assert_eq!(result, Ok(Color::from(RGB::new(1, 2, 3))));
}
} }

View File

@@ -1,3 +1,5 @@
use std::fmt::{Display, UpperHex};
mod foreign_operations; mod foreign_operations;
mod self_operations; mod self_operations;
@@ -18,3 +20,15 @@ impl<const LOW: BaseNumber, const HIGH: BaseNumber> RangedInt<{ LOW }, { HIGH }>
self.0 as f32 self.0 as f32
} }
} }
impl<const LOW: BaseNumber, const HIGH: BaseNumber> Display for RangedInt<{ LOW }, { HIGH }> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl<const LOW: BaseNumber, const HIGH: BaseNumber> UpperHex for RangedInt<{ LOW }, { HIGH }> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
UpperHex::fmt(&self.0, f)
}
}

View File

@@ -1,25 +1,112 @@
use clipboard::ClipboardContext; use arboard::Clipboard;
use clipboard::ClipboardProvider; use colored::Colorize;
use inquire::Select;
use inquire::Text;
use std::env;
use crate::color::Color; use crate::color::Color;
use crate::color::HSL; use crate::color::HSL;
use crate::color::HSV;
use crate::color::RGB; use crate::color::RGB;
mod color; mod color;
pub mod core; pub mod core;
fn example() { fn set_clipboard(output: String) {
let mut ctx: ClipboardContext = ClipboardProvider::new().unwrap(); let mut ctx = Clipboard::new().unwrap();
println!("{:?}", ctx.get_contents()); let result = ctx.set_text(output.clone());
ctx.set_contents("some string".to_owned()).unwrap(); match result {
Ok(_) => {
Text::new(&format!(
"{} Copied {} to clipboard!",
"".truecolor(0, 240, 0),
output
))
.prompt()
.unwrap();
}
Err(_) => {
println!("{} Error on copy to clipboard!", "".truecolor(240, 0, 0),);
}
}
} }
fn read_clipboard() -> Result<String, ()> {
let mut ctx = Clipboard::new().unwrap();
let value = ctx.get_text();
match value {
Ok(clipboard) => return Ok(clipboard),
Err(_) => return Err(()),
}
}
/**
* Params
* --clipboard / -c : read from clipboard first
* --input <String> / -i <String> : dont read from clipboard nor input, simply try parsing the input
*/
fn main() { fn main() {
println!("Hello, world!"); let args: Vec<String> = env::args().collect();
example();
let hsl_color = Color::from(HSL::new(0, 100, 50)); let mut input: String = String::new();
// let rgb_color = Color::from(HSL::new(193, 67, 28)); if args.len() == 2 && (args[1] == "--clipboard" || args[1] == "-c") {
println!("HSL Color: {}", hsl_color.format()); let clipboard_result = read_clipboard();
// println!("RGB Color: {}", rgb_color.format()); match clipboard_result {
Ok(data) => input = data,
Err(()) => {} // Manage error
}
} else if args.len() == 3 && (args[1] == "--input" || args[1] == "-i") {
input = args[2].clone();
} else {
let input_result = Text::new(
"Input color [#<hex>, rgb(<r>,<g>,<b>), hsl(<h>, <s>, <l>), hsv(<h>,<s>,<v>)]",
)
.prompt();
match input_result {
Ok(data) => input = data,
Err(_) => {} // Manage error
}
}
let parsed_color = Color::try_parse(input);
match parsed_color {
Ok(color) => {
let options = list_color_options(color.clone());
let rgb_color: RGB = color.clone().into();
let rgb_tuple = rgb_color.clone().to_u8_tuple();
let selected_format = Select::new(
&format!(
"Encodings of color {}",
"".truecolor(rgb_tuple.0, rgb_tuple.1, rgb_tuple.2)
),
options,
)
.prompt();
match selected_format {
Ok(format) => {
set_clipboard(format.clone());
}
Err(_) => {
let _ = Text::new("Error on input read").prompt();
}
}
}
Err(()) => (),
}
}
fn list_color_options(color: Color) -> Vec<String> {
let mut options: Vec<String> = vec![];
let rgb_color: RGB = color.clone().into();
let hsl_color: HSL = color.clone().into();
let hsv_color: HSV = color.clone().into();
options.push(format!("{:X}", rgb_color));
options.push(format!("{}", rgb_color));
options.push(format!("{}", hsl_color));
options.push(format!("{}", hsv_color));
options
} }