Color parsing

Краен срок
03.11.2022 17:00
Точки
4

Срокът за предаване на решения е отминал

use solution::*;
#[test]
fn test_parsing_hsv() {
let parsed = Color::from_str("hsv(300,50%,70%)");
if let Color::HSV { hue, saturation, value } = parsed {
assert_eq!(hue, 300);
assert_eq!(saturation, 50);
assert_eq!(value, 70);
} else {
panic!("Not the expected result");
}
}
#[test]
fn test_parsing_hex_rgb() {
let parsed = Color::from_str("#abcdef");
if let Color::RGB { red, green, blue } = parsed {
assert_eq!(red, 0xAB);
assert_eq!(green, 0xCD);
assert_eq!(blue, 0xEF);
} else {
panic!("Not the expected result");
}
}

На предното домашно печатахме цветове, сега ще вървим в обратната посока -- парсене. Имате низ, искате да извадите цвят. Тъй като това е предизвикателство, няма да ви дадем цялата информация, която ви трябва за да се справите, но може да намерите помощни средства в стандартната документация, примерно:

pub enum Color {
    RGB {
        red: u8,
        green: u8,
        blue: u8
    },
    HSV {
        hue: u16,
        saturation: u8,
        value: u8,
    }
}

impl Color {
    pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
        Self::RGB { red, green, blue }
    }

    pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
        if hue > 360 || saturation > 100 || value > 100 {
            panic!("Invalid input");
        }

        Self::HSV { hue, saturation, value }
    }

    pub fn from_str(input: &str) -> Self {
        todo!()
    }
}

Очакваме Color::from_str("#ff00ff") да се изпарси до Color::RGB { red: 255, green: 0, blue: 255 } примерно. Очакваме Color::from_str("hsv(360,100%,50%)") да извади Color::HSV { hue: 360, saturation: 100, value: 50 }. Може да приемете, че винаги ще ви даваме валиден вход (т.е. няма нужда да мислите за error handling за момента, panic!-вайте ако се налага), няма да има интервали между запетайките, винаги шестнадесетичната репрезентация на RGB ще бъде с малки букви.

Решения

Андрей
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Андрей

pub enum Color {
RGB {
red: u8,
green: u8,
blue: u8
},
HSV {
hue: u16,
saturation: u8,
value: u8,
}
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Self::RGB { red, green, blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || saturation > 100 || value > 100 {
panic!("Invalid input");
}
Self::HSV { hue, saturation, value }
}
pub fn from_str(input: &str) -> Self {
if input.starts_with("hsv(") {
let parts: Vec<&str> = input[4..input.len() - 1].
split(",").
collect();
Self::new_hsv(
parts[0].parse().unwrap(),
parts[1][..parts[1].len() - 1].parse().unwrap(),
parts[2][..parts[2].len() - 1].parse().unwrap(),
)
} else if input.starts_with("#") {
Self::new_rgb(
u8::from_str_radix(&input[1..=2], 16).unwrap(),
u8::from_str_radix(&input[3..=4], 16).unwrap(),
u8::from_str_radix(&input[5..=6], 16).unwrap(),
)
} else {
panic!("Unknown input format: {}", input)
}
}
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-btp2wl/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.84s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hsv ... ok
test solution_test::test_parsing_hex_rgb ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Венцислав Димитров
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Венцислав Димитров

pub enum Color {
RGB {
red: u8,
green: u8,
blue: u8
},
HSV {
hue: u16,
saturation: u8,
value: u8,
}
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Self::RGB { red, green, blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || saturation > 100 || value > 100 {
panic!("Invalid input");
}
Self::HSV { hue, saturation, value }
}
pub fn from_str(input: &str) -> Self {
if input.starts_with('#') {
Color::RGB {
red: u8::from_str_radix(&input[1..3], 16).unwrap(),
green: u8::from_str_radix(&input[3..5], 16).unwrap(),
blue: u8::from_str_radix(&input[5..7], 16).unwrap(),
}
} else {
let hsv = input
.strip_prefix("hsv(")
.and_then(|s| s.strip_suffix(')'))
.unwrap()
.split(',')
.map(|x| x.trim_matches('%'))
.collect::<Vec<_>>();
Color::HSV {
hue: u16::from_str_radix(hsv[0], 10).unwrap(),
saturation: u8::from_str_radix(hsv[1], 10).unwrap(),
value: u8::from_str_radix(hsv[2], 10).unwrap(),
}
}
}
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-a5mjqv/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.64s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hex_rgb ... ok
test solution_test::test_parsing_hsv ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Адриян Ибовски
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Адриян Ибовски

pub enum Color {
RGB {
red: u8,
green: u8,
blue: u8
},
HSV {
hue: u16,
saturation: u8,
value: u8,
}
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Self::RGB { red, green, blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || saturation > 100 || value > 100 {
panic!("Invalid input");
}
Self::HSV { hue, saturation, value }
}
pub fn from_str(input: &str) -> Self {
if input.chars().nth(0) == Some('#') {
let red = u8::from_str_radix(&input[1..=2], 16).unwrap();
let green = u8::from_str_radix(&input[3..=4], 16).unwrap();
let blue = u8::from_str_radix(&input[5..=6], 16).unwrap();
return Color::new_rgb(red,green,blue);
} else {
let mut v: Vec<u16> = Vec::new();
let mut num: u16 = 0;
let mut flag : bool = false;
for i in input.chars() {
if i.is_numeric() {
num = num * 10 + i.to_digit(10).unwrap() as u16;
flag = true;
} else if flag{
v.push(num);
num = 0;
flag = false;
}
}
return Color::new_hsv(v[0], v[1] as u8, v[2] as u8);
}
}
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-1o8r2pf/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.61s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hex_rgb ... ok
test solution_test::test_parsing_hsv ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Давид Петров
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Давид Петров

use std::str::FromStr;
#[derive(Debug)]
pub struct ParseColorError;
#[derive(PartialEq, Debug)]
pub enum Color {
RGB {
red: u8,
green: u8,
blue: u8
},
HSV {
hue: u16,
saturation: u8,
value: u8,
}
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Self::RGB { red, green, blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || saturation > 100 || value > 100 {
panic!("Invalid input.");
}
Self::HSV { hue, saturation, value }
}
pub fn from_str(input: &str) -> Self {
<Color as FromStr>::from_str(input).unwrap()
}
}
//Color::from_str("#ff00ff")
//Color::from_str("hsv(360,100%,50%)")
impl FromStr for Color {
type Err = ParseColorError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
const ERR: ParseColorError = ParseColorError{};
if s.len() < 7 {
return Err(ERR);
}
if s.len() == 7 {
fn extract(iter: &mut dyn Iterator<Item = char>) -> Option<u8> {
const HEX_BASE: u32 = 16;
let c1 = iter.next()?.to_digit(HEX_BASE)?;
let c2 = iter.next()?.to_digit(HEX_BASE)?;
Some((c1 * HEX_BASE + c2) as u8)
}
let mut iter = s.chars();
let first_char = iter.next().ok_or(ERR)?;
if first_char != '#' {
return Err(ERR);
}
let hex_to_u8: Option<Vec<_>> = (0..=2).map(|_| extract(&mut iter)).collect();
let hex_to_u8 = hex_to_u8.ok_or(ERR)?;
let (red, green, blue) = (hex_to_u8[0], hex_to_u8[1], hex_to_u8[2]);
Ok(Self::RGB { red, green, blue })
} else if &s[0..=3] == "hsv(" && s.chars().last().unwrap() == ')' {
let parts: Vec<&str> = (&s[4..(s.len()-1)]).split(&[',', '%'][..]).collect();
if parts.len() != 5 || parts[2] != "" || parts[4] != "" {
return Err(ERR);
}
let hue = parts[0].parse::<u16>().map_err(|_| ERR)?;
let saturation = parts[1].parse::<u8>().map_err(|_| ERR)?;
let value = parts[3].parse::<u8>().map_err(|_| ERR)?;
Ok(Color::HSV { hue, saturation, value })
} else {
Err(ERR)
}
}
}
#[cfg(test)]
mod tests {
use std::panic::catch_unwind;
use super::*;
#[test]
fn it_works() {
let rgb = Color::new_rgb(1, 2, 3);
assert_eq!(Color::from_str("#010203"), rgb);
let hsv = Color::new_hsv(20, 99, 5);
assert_eq!(Color::from_str("hsv(0020,99%,05%)"), hsv);
assert_eq!(Color::from_str("hsv(20,99%,5%)"), hsv);
}
#[test]
fn panics() {
assert!(catch_unwind(|| Color::new_hsv(370, 2, 2)).is_err());
assert!(catch_unwind(|| Color::from_str("010200z")).is_err());
assert!(catch_unwind(|| Color::from_str("hsv")).is_err());
assert!(catch_unwind(|| Color::from_str("hsv(10,,k%,5%)")).is_err());
assert!(catch_unwind(|| Color::from_str("SOMETHINGVERYVERYWRONG")).is_err());
}
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-1qpub55/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.70s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hex_rgb ... ok
test solution_test::test_parsing_hsv ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Тодор Кюркчиев
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Тодор Кюркчиев

pub enum Color {
RGB {
red: u8,
green: u8,
blue: u8
},
HSV {
hue: u16,
saturation: u8,
value: u8,
}
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Self::RGB { red, green, blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || saturation > 100 || value > 100 {
panic!("Invalid input");
}
Self::HSV { hue, saturation, value }
}
pub fn from_str(input: &str) -> Self {
if input.starts_with("#") {
let red = u8::from_str_radix(&input[1..3], 16).unwrap();
let green = u8::from_str_radix(&input[3..5], 16).unwrap();
let blue = u8::from_str_radix(&input[5..7], 16).unwrap();
Color::new_rgb(red, green, blue)
} else if input.starts_with("hsv(") {
let mut input = input[4..(input.len() - 1)].split(',');
let hue = input.next().unwrap().parse::<u16>().unwrap();
let saturation = input.next().unwrap().trim_end_matches('%').parse::<u8>().unwrap();
let value = input.next().unwrap().trim_end_matches('%').parse::<u8>().unwrap();
Color::new_hsv(hue, saturation, value)
} else {
panic!("Invalid input");
}
}
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-1vyrdse/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.57s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hex_rgb ... ok
test solution_test::test_parsing_hsv ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Христо Жаблянов
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Христо Жаблянов

pub enum Color {
RGB { red: u8, green: u8, blue: u8 },
HSV { hue: u16, saturation: u8, value: u8 },
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Self::RGB { red, green, blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || saturation > 100 || value > 100 {
panic!("Invalid input");
}
Self::HSV {
hue,
saturation,
value,
}
}
pub fn from_str(input: &str) -> Self {
if input.is_empty() {
panic!("Empty source")
}
if input.chars().nth(0).unwrap() == '#' {
Color::RGB {
red: u8::from_str_radix(&input[1..3], 16).unwrap(),
green: u8::from_str_radix(&input[3..5], 16).unwrap(),
blue: u8::from_str_radix(&input[5..7], 16).unwrap(),
}
} else {
let mut beg = 4;
let mut end = input[beg..].find(",").unwrap() + beg;
let hue = input[beg..end].parse().unwrap();
beg = end + 1;
end = input[beg..].find("%").unwrap() + beg;
let saturation = input[beg..end].parse().unwrap();
beg = end + 2;
end = input[beg..].find("%").unwrap() + beg;
let value = input[beg..end].parse().unwrap();
Color::HSV {
hue,
saturation,
value,
}
}
}
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-8w6gh3/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.64s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hsv ... ok
test solution_test::test_parsing_hex_rgb ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Климент Бербатов
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Климент Бербатов

pub enum Color {
RGB {
red: u8,
green: u8,
blue: u8
},
HSV {
hue: u16,
saturation: u8,
value: u8,
}
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Self::RGB { red, green, blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || saturation > 100 || value > 100 {
panic!("Invalid input");
}
Self::HSV { hue, saturation, value }
}
pub fn from_str(input: &str) -> Self {
let ch: Option<char> = input.chars().nth(0);
if ch == Some('#') {
let r: u8 = u8::from_str_radix(&input[1..3], 16).unwrap();
let g: u8 = u8::from_str_radix(&input[3..5], 16).unwrap();
let b: u8 = u8::from_str_radix(&input[5..7], 16).unwrap();
Self::new_rgb(r, g, b)
// Self::new_rgb(0, 0, 0)
} else {
let m: (u16, u8, u8) = str_to_tuple(&input[3..]);
Self::new_hsv(m.0, m.1, m.2)
}
}
}
fn str_to_tuple(input: &str) -> (u16, u8, u8) {
// println!("{:?}",&input);
let mut it: std::str::Chars = input.chars();
let mut i: usize = 0;
while let Some(c) = it.next() {
if c == ',' {
break;
}
i = i + 1;
}
let hue: u16 = u16::from_str_radix(&input[1..i], 10).unwrap();
let mut j: usize = i + 1;
while let Some(c) = it.next() {
i = i + 1;
if c == '%' {
break;
}
// i = i+1;
}
let saturation: u8 = u8::from_str_radix(&input[j..i], 10).unwrap();
j = i + 2;
while let Some(c) = it.next() {
i = i + 1;
if c == '%' {
break;
}
}
let value: u8 = u8::from_str_radix(&input[j..i], 10).unwrap();
(hue, saturation, value)
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-6wc28z/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.56s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hex_rgb ... ok
test solution_test::test_parsing_hsv ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Ангел Пенчев
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Ангел Пенчев

use std::str::from_utf8;
#[derive(Debug, PartialEq)]
pub enum Color {
RGB {
red: u8,
green: u8,
blue: u8,
},
HSV {
hue: u16,
saturation: u8,
value: u8,
},
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Self::RGB { red, green, blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || saturation > 100 || value > 100 {
panic!("Invalid input");
}
Self::HSV { hue, saturation, value }
}
/// Converts a color string to a Color enum.
///
/// # Arguments
/// * `color` - A string representing a color in the format `#rrggbb` or `hsv(h,s%,v%)`.
///
/// # Returns
/// A Color enum representing the color.
///
/// # Errors
/// If the color string is not in the correct format, an error is returned.
///
/// # Examples
/// ```
/// use color_parsing::Color;
///
/// let color1 = Color::from_str("#ff0000");
/// assert_eq!(color1, Color::RGB { red: 255, green: 0, blue: 0 });
///
/// let color2 = Color::from_str("hsv(0,100%,100%)");
/// assert_eq!(color2, Color::HSV { hue: 0, saturation: 100, value: 100 });
/// ```
pub fn from_str(input: &str) -> Self {
if input.starts_with("#") {
let sanitized_input = input.strip_prefix("#").unwrap();
match sanitized_input
.as_bytes()
.chunks(2)
.map(from_utf8)
.collect::<Result<Vec<&str>, _>>()
.unwrap()
.as_slice() {
[red, green, blue] => {
let red: u8 = u8::from_str_radix(red, 16).unwrap();
let green: u8 = u8::from_str_radix(green, 16).unwrap();
let blue: u8 = u8::from_str_radix(blue, 16).unwrap();
Self::new_rgb(red, green, blue)
}
_ => panic!("Invalid RGB string.")
}
} else if input.starts_with("hsv") {
let sanitized_input = input
.strip_prefix("hsv(")
.and_then(|input: &str| input.strip_suffix(")"))
.unwrap()
.replace("%", "")
.replace(" ", "");
match sanitized_input.split(",").collect::<Vec<_>>().as_slice() {
[hue, saturation, value] => {
let hue = hue.parse::<u16>().unwrap();
let saturation = saturation.parse::<u8>().unwrap();
let value = value.parse::<u8>().unwrap();
Self::new_hsv(hue, saturation, value)
}
_ => panic!("Invalid HSV string.")
}
} else {
panic!("Invalid string.")
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn from_string_rgb() {
let color = Color::from_str("#FF0000");
assert_eq!(color, Color::new_rgb(255, 0, 0));
let color = Color::from_str("#00FF00");
assert_eq!(color, Color::new_rgb(0, 255, 0));
let color = Color::from_str("#0000FF");
assert_eq!(color, Color::new_rgb(0, 0, 255));
let color = Color::from_str("#FFFFFF");
assert_eq!(color, Color::new_rgb(255, 255, 255));
}
#[test]
fn from_string_hsv() {
let color = Color::from_str("hsv(0,100%,100%)");
assert_eq!(color, Color::new_hsv(0, 100, 100));
let color = Color::from_str("hsv(360,100%,100%)");
assert_eq!(color, Color::new_hsv(360, 100, 100));
let color = Color::from_str("hsv(0,0%,0%)");
assert_eq!(color, Color::new_hsv(0, 0, 0));
let color = Color::from_str("hsv(360,0%,0%)");
assert_eq!(color, Color::new_hsv(360, 0, 0));
}
#[test]
#[should_panic]
fn from_string_invalid() {
Color::from_str("invalid");
}
#[test]
#[should_panic]
fn from_string_invalid_rgb() {
Color::from_str("#FFFF");
}
#[test]
#[should_panic]
fn from_string_invalid_hsv() {
Color::from_str("hsv(0,100%,100%,100%)");
}
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-17z1bln/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.69s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hex_rgb ... ok
test solution_test::test_parsing_hsv ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Петко Каменов
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Петко Каменов

pub enum Color {
RGB { red: u8, green: u8, blue: u8 },
HSV { hue: u16, saturation: u8, value: u8 },
}
impl Color {
/// Конструира нова стойност от вариант `RGB` с дадените стойности за червено, зелено и синьо.
///
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Color::RGB { red, green, blue }
}
/// Конструира нова стойност от вариант `HSV` с дадените стойности.
///
/// В случай, че hue е над 360 или saturation или value са над 100, очакваме да `panic!`-нете с
/// каквото съобщение си изберете.
///
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
assert!(hue <= 360, "hue must be <= 360");
assert!(saturation <= 100, "saturation must be <= 100");
assert!(value <= 100, "value must be <= 100");
Color::HSV {
hue,
saturation,
value,
}
}
/// Ако `self` е `RGB`, тогава връщате неговите `red`, `green`, `blue` компоненти в този ред.
/// Иначе, `panic!`-вате с каквото съобщение си изберете.
///
pub fn unwrap_rgb(&self) -> (u8, u8, u8) {
match self {
Color::RGB { red, green, blue } => (*red, *green, *blue),
_ => panic!("Color is not RGB"),
}
}
/// Ако `self` е `HSV`, тогава връщате неговите `hue`, `saturation`, `value` компоненти в този
/// ред. Иначе, `panic!`-вате с каквото съобщение си изберете.
///
pub fn unwrap_hsv(&self) -> (u16, u8, u8) {
match self {
Color::HSV {
hue,
saturation,
value,
} => (*hue, *saturation, *value),
_ => panic!("Color is not HSV"),
}
}
/// В случай, че варианта на `self` е `RGB`, очакваме низ със съдържание `#rrggbb`, където
/// червения, зеления и синия компонент са форматирани в шестнадесетична система, и всеки от тях е
/// точно два символа с малки букви (запълнени с нули).
///
/// Ако варианта е `HSV`, очакваме низ `hsv(h,s%,v%)`, където числата са си напечатани в
/// десетичната система, без водещи нули, без интервали след запетаите, вторите две завършващи на
/// `%`.
///
pub fn to_string(&self) -> String {
match self {
Color::RGB { red, green, blue } => format!("#{:02x}{:02x}{:02x}", red, green, blue),
Color::HSV {
hue,
saturation,
value,
} => format!("hsv({},{}%,{}%)", hue, saturation, value),
}
}
/// Инвертира цвят покомпонентно -- за всяка от стойностите се взема разликата с максимума.
///
pub fn invert(&self) -> Self {
match self {
Color::RGB { red, green, blue } => Color::RGB {
red: 255 - red,
green: 255 - green,
blue: 255 - blue,
},
Color::HSV {
hue,
saturation,
value,
} => Color::HSV {
hue: 360 - hue,
saturation: 100 - saturation,
value: 100 - value,
},
}
}
pub fn from_str(input: &str) -> Self {
let first_char = input.chars().next().unwrap();
match first_char {
'#' => {
let red = u8::from_str_radix(&input[1..3], 16).unwrap();
let green = u8::from_str_radix(&input[3..5], 16).unwrap();
let blue = u8::from_str_radix(&input[5..7], 16).unwrap();
Color::new_rgb(red, green, blue)
}
'h' => {
let hue: u16 = input[4..input.find(',').unwrap()].parse().unwrap();
let saturation: u8 = input[input.find(',').unwrap() + 1..input.find('%').unwrap()]
.parse()
.unwrap();
let value: u8 = input[input.rfind(',').unwrap() + 1..input.rfind('%').unwrap()]
.parse()
.unwrap();
Color::new_hsv(hue, saturation, value)
}
_ => panic!("Invalid color format"),
}
}
}
#[cfg(test)]
mod tests {
use crate::Color;
#[test]
fn test_from_str_rgb() {
let color1 = Color::from_str("#ff0000");
let color2 = Color::from_str("#00ff00");
let color3 = Color::from_str("#ff00ff");
let color4 = Color::from_str("#000000");
let color5 = Color::from_str("#ffffff");
let color6 = Color::from_str("#3423ff");
let color7 = Color::from_str("#b311a2");
let color8 = Color::from_str("#abbacf");
assert_eq!(color1.unwrap_rgb(), (255, 0, 0));
assert_eq!(color2.unwrap_rgb(), (0, 255, 0));
assert_eq!(color3.unwrap_rgb(), (255, 0, 255));
assert_eq!(color4.unwrap_rgb(), (0, 0, 0));
assert_eq!(color5.unwrap_rgb(), (255, 255, 255));
assert_eq!(color6.unwrap_rgb(), (52, 35, 255));
assert_eq!(color7.unwrap_rgb(), (179, 17, 162));
assert_eq!(color8.unwrap_rgb(), (171, 186, 207));
}
#[test]
fn test_from_str_hsv() {
let color1 = Color::from_str("hsv(0,100%,100%)");
let color2 = Color::from_str("hsv(120,100%,100%)");
let color3 = Color::from_str("hsv(240,100%,100%)");
let color4 = Color::from_str("hsv(0,0%,0%)");
let color5 = Color::from_str("hsv(0,0%,100%)");
let color6 = Color::from_str("hsv(0,100%,50%)");
let color7 = Color::from_str("hsv(120,50%,50%)");
let color8 = Color::from_str("hsv(240,50%,50%)");
assert_eq!(color1.unwrap_hsv(), (0, 100, 100));
assert_eq!(color2.unwrap_hsv(), (120, 100, 100));
assert_eq!(color3.unwrap_hsv(), (240, 100, 100));
assert_eq!(color4.unwrap_hsv(), (0, 0, 0));
assert_eq!(color5.unwrap_hsv(), (0, 0, 100));
assert_eq!(color6.unwrap_hsv(), (0, 100, 50));
assert_eq!(color7.unwrap_hsv(), (120, 50, 50));
assert_eq!(color8.unwrap_hsv(), (240, 50, 50));
}
#[test]
fn test_new_rgb() {
let color = Color::new_rgb(255, 0, 0);
match color {
Color::RGB { red, green, blue } => {
assert_eq!(red, 255);
assert_eq!(green, 0);
assert_eq!(blue, 0);
}
_ => panic!("Expected RGB color"),
}
}
#[test]
fn test_new_hsv() {
let color = Color::new_hsv(360, 100, 100);
match color {
Color::HSV {
hue,
saturation,
value,
} => {
assert_eq!(hue, 360);
assert_eq!(saturation, 100);
assert_eq!(value, 100);
}
_ => panic!("Expected HSV color"),
}
}
#[test]
#[should_panic]
fn test_new_hsv_panic() {
Color::new_hsv(361, 100, 100);
}
#[test]
#[should_panic]
fn test_new_hsv_panic2() {
Color::new_hsv(24, 101, 100);
}
#[test]
fn test_unwrap_rgb() {
let color = Color::new_rgb(255, 0, 0);
let (red, green, blue) = color.unwrap_rgb();
assert_eq!(red, 255);
assert_eq!(green, 0);
assert_eq!(blue, 0);
}
#[test]
#[should_panic]
fn test_unwrap_rgb_panic() {
let color = Color::new_hsv(360, 100, 100);
color.unwrap_rgb();
}
#[test]
fn test_unwrap_hsv() {
let color = Color::new_hsv(360, 100, 100);
let (hue, saturation, value) = color.unwrap_hsv();
assert_eq!(hue, 360);
assert_eq!(saturation, 100);
assert_eq!(value, 100);
}
#[test]
#[should_panic]
fn test_unwrap_hsv_panic() {
let color = Color::new_rgb(255, 0, 0);
color.unwrap_hsv();
}
#[test]
fn test_to_string_rgb() {
let color1 = Color::new_rgb(255, 1, 255);
let color2 = Color::new_rgb(0, 0, 0);
let color3 = Color::new_rgb(255, 255, 255);
assert_eq!(color1.to_string(), "#ff01ff");
assert_eq!(color2.to_string(), "#000000");
assert_eq!(color3.to_string(), "#ffffff");
}
#[test]
fn test_to_string_hsv() {
let color1 = Color::new_hsv(360, 100, 100);
let color2 = Color::new_hsv(0, 0, 0);
let color3 = Color::new_hsv(0, 0, 100);
assert_eq!(color1.to_string(), "hsv(360,100%,100%)");
assert_eq!(color2.to_string(), "hsv(0,0%,0%)");
assert_eq!(color3.to_string(), "hsv(0,0%,100%)");
}
#[test]
fn test_invert_rgb() {
let color1 = Color::new_rgb(255, 0, 255);
let color2 = Color::new_rgb(0, 0, 0);
let color3 = Color::new_rgb(254, 1, 3);
assert_eq!(color1.invert().unwrap_rgb(), (0, 255, 0));
assert_eq!(color2.invert().unwrap_rgb(), (255, 255, 255));
assert_eq!(color3.invert().unwrap_rgb(), (1, 254, 252));
assert_eq!(color1.invert().to_string(), "#00ff00");
assert_eq!(color2.invert().to_string(), "#ffffff");
assert_eq!(color3.invert().to_string(), "#01fefc");
}
#[test]
fn test_invert_hsv() {
let color1 = Color::new_hsv(0, 50, 0);
let color2 = Color::new_hsv(150, 30, 45);
let color3 = Color::new_hsv(10, 1, 78);
assert_eq!(color1.invert().unwrap_hsv(), (360, 50, 100));
assert_eq!(color2.invert().unwrap_hsv(), (210, 70, 55));
assert_eq!(color3.invert().unwrap_hsv(), (350, 99, 22));
assert_eq!(color1.invert().to_string(), "hsv(360,50%,100%)");
assert_eq!(color2.invert().to_string(), "hsv(210,70%,55%)");
assert_eq!(color3.invert().to_string(), "hsv(350,99%,22%)");
}
#[test]
fn test_basic() {
let color1 = Color::new_rgb(0, 0, 0);
assert_eq!(color1.unwrap_rgb().0, 0);
assert_eq!(&color1.to_string()[0..1], "#");
let color2 = Color::new_hsv(0, 0, 0);
assert_eq!(color2.unwrap_hsv().0, 0);
assert_eq!(color1.invert().unwrap_rgb().0, 255);
}
#[test]
fn test_basic_2() {
let color1 = Color::new_rgb(255, 255, 255);
assert_eq!(color1.unwrap_rgb().0, 255);
assert_eq!(&color1.to_string()[0..1], "#");
let color2 = Color::new_hsv(360, 100, 100);
assert_eq!(color2.unwrap_hsv().0, 360);
assert_eq!(color1.invert().unwrap_rgb().0, 0);
}
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-18u23ku/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.62s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hex_rgb ... ok
test solution_test::test_parsing_hsv ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Стойчо Кьосев
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Стойчо Кьосев

pub enum Color {
RGB { red: u8, green: u8, blue: u8 },
HSV { hue: u16, saturation: u8, value: u8 },
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Self::RGB { red, green, blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || saturation > 100 || value > 100 {
panic!("Invalid input");
}
Self::HSV { hue, saturation, value }
}
pub fn from_str(input: &str) -> Self {
if let ("hsv(", xs) = input.split_at(4) {
let mut numbers = xs.split_terminator(&[',', ')', '%']);
let h_str = numbers.next().unwrap();
let s_str = numbers.next().unwrap();
numbers.next();
let v_str = numbers.next().unwrap();
let hue = u16::from_str_radix(h_str, 10).unwrap();
let saturation = u8::from_str_radix(s_str, 10).unwrap();
let value = u8::from_str_radix(v_str, 10).unwrap();
Color::HSV { hue, saturation, value }
}
else if let ("#", xs) = input.split_at(1) {
let (first, rest) = xs.split_at(2);
let (second, third) = rest.split_at(2);
let red = u8::from_str_radix(first, 16).unwrap();
let green = u8::from_str_radix(second, 16).unwrap();
let blue = u8::from_str_radix(third, 16).unwrap();
Color::RGB { red, green, blue }
}
else {
panic!("Invalid input");
}
}
pub fn unwrap_rgb(&self) -> (u8, u8, u8) {
match self {
Color::RGB { red, green, blue } => (*red, *green, *blue),
_ => panic!("Cannot unwrap non-rgb type to (u8, u8, u8)")
}
}
pub fn unwrap_hsv(&self) -> (u16, u8, u8) {
match self {
Color::HSV { hue, saturation, value } => (*hue, *saturation, *value),
_ => panic!("Cannot unwrap non-hsv type to (u16, u8, u8)")
}
}
}
#[cfg(test)]
mod tests {
use crate::Color;
#[test]
fn basic_rgb_test() {
let res = Color::from_str("#000000");
let t = res.unwrap_rgb();
assert_eq!(t, (0, 0, 0));
}
#[test]
fn basic_hsv_test() {
let res = Color::from_str("hsv(10,10%,10%)");
let t = res.unwrap_hsv();
assert_eq!(t, (10, 10, 10));
}
#[test]
fn hard_rgb_test() {
let res = Color::from_str("#198235");
let t = res.unwrap_rgb();
assert_eq!(t, (25, 130, 53));
}
#[test]
fn hard_hsv_test() {
let res = Color::from_str("hsv(100,100%,99%)");
let t = res.unwrap_hsv();
assert_eq!(t, (100, 100, 99));
}
#[test]
#[should_panic(expected = "Invalid input")]
fn panic_on_invalid_input() {
let _ = Color::from_str("!(Tests are fun)");
}
#[test]
#[should_panic(expected = "called `Result::unwrap()` on an `Err` value: ParseIntError { kind: PosOverflow }")]
fn panic_on_overflow_input() {
let _ = Color::from_str("hsv(400,400%,400%)");
}
#[test]
fn stolen_tests() {
let rgb = Color::from_str("#ff00ff");
let hsv = Color::from_str("hsv(360,100%,50%)");
let pair_rgb = rgb.unwrap_rgb();
let pair_hsv = hsv.unwrap_hsv();
assert_eq!(pair_hsv, (360, 100, 50));
assert_eq!(pair_rgb, (255, 0, 255));
}
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-1k02pvr/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.56s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hex_rgb ... ok
test solution_test::test_parsing_hsv ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Алекс Божинов
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Алекс Божинов

#[derive(Debug)]
pub enum Color {
RGB {
red: u8,
green: u8,
blue: u8
},
HSV {
hue: u16,
saturation: u8,
value: u8,
}
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Self::RGB { red, green, blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || saturation > 100 || value > 100 {
panic!("Invalid input");
}
Self::HSV { hue, saturation, value }
}
pub fn from_str(input: &str) -> Self {
if input.len() == 7{
let (_sign, full_number) = input.split_at(1);
let (red_hex, rest_hexes) = full_number.split_at(2);
let (green_hex, blue_hex) = rest_hexes.split_at(2);
Self::new_rgb(
u8::from_str_radix(red_hex, 16).unwrap(),
u8::from_str_radix(green_hex, 16).unwrap(),
u8::from_str_radix(blue_hex, 16).unwrap()
)
}else{
let splited_symbols: Vec<&str> = input.split(',').collect();
Self::new_hsv(
u16::from_str_radix(splited_symbols[0].strip_prefix("hsv(").unwrap(), 10).unwrap(),
u8::from_str_radix(splited_symbols[1].strip_suffix('%').unwrap(), 10).unwrap(),
u8::from_str_radix(splited_symbols[2].strip_suffix("%)").unwrap(), 10).unwrap()
)
}
}
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-15r4fug/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.64s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hex_rgb ... ok
test solution_test::test_parsing_hsv ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Искендер Чобанов
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Искендер Чобанов

#[derive(Debug)]
pub enum Color {
RGB {
red: u8,
green: u8,
blue: u8
},
HSV {
hue: u16,
saturation: u8,
value: u8,
}
}
impl Color {
/// Конструира нова стойност от вариант `RGB` с дадените стойности за червено, зелено и синьо.
///
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Color::RGB{red,green,blue}
}
/// Конструира нова стойност от вариант `HSV` с дадените стойности.
///
/// В случай, че hue е над 360 или saturation или value са над 100, очакваме да `panic!`-нете с
/// каквото съобщение си изберете.
///
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || value > 100 || saturation > 100
{
panic!("hsv upper limits: (hue(360),value(100),saturation(100)");
}
Color::HSV{hue,saturation,value}
}
pub fn unwrap_rgb(&self) -> (u8, u8, u8) {
match &self
{
Color::RGB{red,green,blue} => (*red,*green,*blue),
_ => panic!("if you read this please try unwrap_hsv()")
}
}
/// Ако `self` е `HSV`, тогава връщате неговите `hue`, `saturation`, `value` компоненти в този
/// ред. Иначе, `panic!`-вате с каквото съобщение си изберете.
///
pub fn unwrap_hsv(&self) -> (u16, u8, u8) {
match &self
{
Color::HSV{hue,saturation,value} => (*hue,*saturation,*value),
_ => panic!("if you read this please try unwrap_rgb()")
}
}
pub fn to_string(&self) -> String {
match &self
{
Color::RGB{red,green,blue} =>
{
let mut string = String::from(format!("#{:02x}",red));
string.push_str(&format!("{:02x}",green));
string.push_str(&format!("{:02x}",blue));
return string;
},
Color::HSV{hue,saturation,value} =>
{
let mut string = String::from(format!("hsv({},",hue));
string.push_str(&format!("{}%,",saturation));
string.push_str(&format!("{}%)",value));
return string;
}
}
}
pub fn invert(&self) -> Self {
match &self
{
Color::RGB{red,green,blue} => {
let max_all = u8::MAX;
Color::new_rgb(max_all-*red,max_all-*green,max_all-*blue)
},
Color::HSV{hue,saturation,value} => {
let max_first = 360;
let max_rest = 100;
Color::new_hsv(max_first - hue,max_rest-saturation,max_rest-value)
}
}
}
pub fn from_str(input: &str) -> Self {
let hash_check = input.chars().nth(0).unwrap();
if hash_check == '#'
{
let red: u8 = u8::from_str_radix(&input[1..3],16).unwrap();
println!("{}",red);
let green: u8 = u8::from_str_radix(&input[3..5],16).unwrap();
let blue: u8 = u8::from_str_radix(&input[5..7],16).unwrap();
return Color::new_rgb(red,green,blue);
}
else
{
let v = get_hsv_nums(input);
let hue: u16 = v[0].parse().unwrap();
let saturation: u8 = v[1].parse().unwrap();
let value: u8 = v[2].parse().unwrap();
return Color::new_hsv(hue,saturation,value);
}
}
}
fn get_hsv_nums(input: &str)->Vec<&str>
{
let v = input.split(',').collect::<Vec<&str>>();
let mut fv : Vec<&str> = Vec::new();
fv.push(&v[0][4..]);
fv.push(&v[1][..v[1].len()-1]);
fv.push(&v[2][..v[2].len()-2]);
fv
}
#[test]
fn test_rgb_parsing() {
assert_eq!(Color::from_str("#01147b").unwrap_rgb(),Color::new_rgb(1, 20, 123).unwrap_rgb());
assert_eq!(Color::from_str("#ffffff").unwrap_rgb(),Color::new_rgb(255, 255, 255).unwrap_rgb());
assert_eq!(Color::from_str("#000000").unwrap_rgb(),Color::new_rgb(0, 0, 0).unwrap_rgb());
}
#[test]
fn test_hsv_parsing()
{
assert_eq!(Color::from_str("hsv(0,0%,0%)").unwrap_hsv(),Color::new_hsv(0,0,0).unwrap_hsv());
assert_eq!(Color::from_str("hsv(90,3%,99%)").unwrap_hsv(),Color::new_hsv(90,3,99).unwrap_hsv());
assert_eq!(Color::from_str("hsv(360,100%,100%)").unwrap_hsv(),Color::new_hsv(360,100,100).unwrap_hsv());
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-czkeze/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.68s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hex_rgb ... ok
test solution_test::test_parsing_hsv ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Николай Паев
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Николай Паев

#[derive(Debug, PartialEq)]
pub enum Color {
RGB { red: u8, green: u8, blue: u8 },
HSV { hue: u16, saturation: u8, value: u8 },
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Self::RGB { red, green, blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || saturation > 100 || value > 100 {
panic!("Invalid input");
}
Self::HSV {
hue,
saturation,
value,
}
}
pub fn from_str(input: &str) -> Self {
let mut vec = input.chars();
match vec.next() {
Some('#') => {
let mut numbers: [String; 3] = Default::default();
for i in 0..numbers.len() {
numbers[i].push(vec.next().unwrap());
numbers[i].push(vec.next().unwrap());
}
let red = u8::from_str_radix(&numbers[0], 16).unwrap();
let green = u8::from_str_radix(&numbers[1], 16).unwrap();
let blue = u8::from_str_radix(&numbers[2], 16).unwrap();
Self::new_rgb(red, green, blue)
}
Some('h') => {
let csv_string = vec
.filter(|c| c.is_numeric() || *c == ',')
.collect::<String>();
let numbers = csv_string.split(',').collect::<Vec<_>>();
let hue = u16::from_str_radix(&numbers[0], 10).unwrap();
let saturation = u8::from_str_radix(&numbers[1], 10).unwrap();
let value = u8::from_str_radix(&numbers[2], 10).unwrap();
Self::new_hsv(hue, saturation, value)
}
_ => panic!(),
}
}
}
#[cfg(test)]
mod test {
use super::Color;
#[test]
fn hex_test() {
assert_eq!(Color::from_str("#ff00ff"), Color::new_rgb(255, 0, 255));
assert_eq!(Color::from_str("#000000"), Color::new_rgb(0, 0, 0));
assert_eq!(Color::from_str("#ff01ff"), Color::new_rgb(255, 1, 255));
}
#[test]
fn hsv_test() {
assert_eq!(Color::from_str("hsv(360,100%,50%)"), Color::new_hsv(360, 100, 50));
assert_eq!(Color::from_str("hsv(0,0%,0%)"), Color::new_hsv(0, 0, 0));
assert_eq!(Color::from_str("hsv(360,100%,100%)"), Color::new_hsv(360, 100, 100));
}
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-1oehwkn/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.67s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hex_rgb ... ok
test solution_test::test_parsing_hsv ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Йордан Илиев
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Йордан Илиев

pub enum Color {
RGB {
red: u8,
green: u8,
blue: u8
},
HSV {
hue: u16,
saturation: u8,
value: u8,
}
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Self::RGB { red, green, blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || saturation > 100 || value > 100 {
panic!("Invalid input");
}
Self::HSV { hue, saturation, value }
}
pub fn from_str(input: &str) -> Self {
if input.starts_with("#") {
Color::RGB {
red: u8::from_str_radix(&input[1..=2], 16).unwrap(),
green: u8::from_str_radix(&input[3..=4], 16).unwrap(),
blue: u8::from_str_radix(&input[5..=6], 16).unwrap(),
}
}
else {
let values_and_commas = &input[4..(input.len() - 1)];
let hsv_values: Vec<&str> = values_and_commas.split(",").collect();
let hue = u16::from_str_radix(hsv_values[0], 10).unwrap();
let saturation_str = &hsv_values[1][0..(hsv_values[1].len() - 1)];
let saturation = u8::from_str_radix(saturation_str, 10).unwrap();
let value_str = &hsv_values[2][0..(hsv_values[2].len() - 1)];
let value = u8::from_str_radix(value_str, 10).unwrap();
Color::HSV {
hue,
saturation,
value
}
}
}
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-1mg66t4/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.63s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hex_rgb ... ok
test solution_test::test_parsing_hsv ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Владимир Радев
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Владимир Радев

use std::{process::Output, str::FromStr};
#[derive(Debug)]
pub enum Color {
RGB { red: u8, green: u8, blue: u8 },
HSV { hue: u16, saturation: u8, value: u8 },
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Self::RGB { red, green, blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || saturation > 100 || value > 100 {
panic!("Invalid input");
}
Self::HSV {
hue,
saturation,
value,
}
}
// Color::from_str("#ff00ff") -> Color::RGB { red: 255, green: 0, blue: 255 }
// Color::from_str("hsv(360,100%,50%)") -> Color::HSV { hue: 360, saturation: 100, value: 50 }
pub fn from_str(input: &str) -> Self {
let arr_char = input.chars().collect::<Vec<char>>();
let res = match &arr_char[0] {
'#' => {
let red = u8::from_str_radix(&input[1..=2], 16).unwrap_or_else(|e| panic!("{}", e));
let green =
u8::from_str_radix(&input[3..=4], 16).unwrap_or_else(|e| panic!("{}", e));
let blue =
u8::from_str_radix(&input[5..=6], 16).unwrap_or_else(|e| panic!("{}", e));
Color::RGB {
red: red,
green: green,
blue: blue,
}
}
'h' => {
let mut t = input
.split(&[',', '%', '(', ')'][..])
.collect::<Vec<&str>>();
//["hsv", "360", "100", "", "50", "", ""] <- that is it what we received after above operation
let hue = u16::from_str(t[1]).unwrap_or_else(|e| panic!("{}", e));
let saturation = u8::from_str(t[2]).unwrap_or_else(|e| panic!("{}", e));
let value = u8::from_str(t[4]).unwrap_or_else(|e| panic!("{}", e));
Color::HSV {
hue: hue,
saturation: saturation,
value: value,
}
}
_ => panic!("Not found converting between given input: &str and Color !"),
};
res
}
}
pub fn add(left: usize, right: usize) -> usize {
left + right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
#[test]
fn basic_test() {
let a = Color::from_str("#ff0010");
let b = match &a {
Color::RGB { red, green, blue } => (*red, *green, *blue),
_ => (0, 0, 0),
};
assert_eq!(b, (255, 0, 16));
let a = Color::from_str("hsv(360,100%,50%)");
let b = match &a {
Color::HSV {
hue,
saturation,
value,
} => (*hue, *saturation, *value),
_ => (0, 0, 0),
};
assert_eq!(b, (360, 100, 50));
}
#[test]
fn edge_cases_test() {
let a = Color::from_str("#000000");
let b = match &a {
Color::RGB { red, green, blue } => (*red, *green, *blue),
_ => (1, 1, 1),
};
assert_eq!(b, (0, 0, 0));
let a = Color::from_str("#ffffff");
let b = match &a {
Color::RGB { red, green, blue } => (*red, *green, *blue),
_ => (0, 0, 0),
};
assert_eq!(b, (255, 255, 255));
let a = Color::from_str("hsv(0,0%,0%)");
let b = match &a {
Color::HSV {
hue,
saturation,
value,
} => (*hue, *saturation, *value),
_ => (1, 1, 1),
};
assert_eq!(b, (0, 0, 0));
let a = Color::from_str("hsv(360,100%,100%)");
let b = match &a {
Color::HSV {
hue,
saturation,
value,
} => (*hue, *saturation, *value),
_ => (0, 0, 0),
};
assert_eq!(b, (360, 100, 100));
}
#[test]
fn random_test() {
let a = Color::from_str("hsv(261,69%,43%)");
let b = match &a {
Color::HSV {
hue,
saturation,
value,
} => (*hue, *saturation, *value),
_ => (0, 0, 0),
};
assert_eq!(b, (261, 69, 43));
let a = Color::from_str("#597cfd");
let b = match &a {
Color::RGB { red, green, blue } => (*red, *green, *blue),
_ => (0, 0, 0),
};
assert_eq!(b, (89, 124, 253));
}
#[test]
fn just_to_know_test() {
//let a = Color::from_str("hsv(360,256%,0%)"); //panic /w mes: "number too large to fit in target type"
//let b = Color::from_str("sv(360,255%,0%)"); //panic /w mes: "Not found converting between given input: &str and Color ! "
//let c = Color::from_str("hsv(-360,255%,0%)"); //panic /w mes: "invalid digit found in string "
assert_eq!(1,1);
}
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-1ypdw7w/solution)
warning: unused import: `process::Output`
 --> src/lib.rs:1:11
  |
1 | use std::{process::Output, str::FromStr};
  |           ^^^^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: variable does not need to be mutable
  --> src/lib.rs:44:21
   |
44 |                 let mut t = input
   |                     ----^
   |                     |
   |                     help: remove this `mut`
   |
   = note: `#[warn(unused_mut)]` on by default

warning: `solution` (lib) generated 2 warnings
    Finished test [unoptimized + debuginfo] target(s) in 0.64s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hex_rgb ... ok
test solution_test::test_parsing_hsv ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Теодор Борисов
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Теодор Борисов

use std::vec;
trait Extract {
fn extract_rgb(input: &str) -> Color;
fn extract_hsv(input: &str) -> Color;
}
pub enum Color {
RGB {
red: u8,
green: u8,
blue: u8
},
HSV {
hue: u16,
saturation: u8,
value: u8,
}
}
impl Extract for Color {
fn extract_rgb(input: &str)-> Color {
let red = u8::from_str_radix(&input[1..=2], 16).unwrap();
let green = u8::from_str_radix(&input[3..=4], 16).unwrap();
let blue = u8::from_str_radix(&input[5..=6], 16).unwrap();
return Color::new_rgb(red, green, blue);
}
fn extract_hsv(input: &str) -> Color {
let vec_hsv: Vec<char> = input.chars().collect();
let mut vec_params: Vec<u16> = vec![0, 0, 0];
let vec_size = vec_hsv.len();
let mut j: usize = 0;
for i in 0..vec_size {
if vec_hsv[i].is_numeric() {
vec_params[j] = vec_params[j] * 10 + vec_hsv[i].to_digit(10).unwrap() as u16;
} else if vec_hsv[i] == ',' {
j += 1;
}
}
let hue = vec_params[0];
let saturation = vec_params[1] as u8;
let value = vec_params[2] as u8;
if hue > 360 || saturation > 100 || value > 100 {
panic!("Грешни стойности за HSV!");
}
return Color::new_hsv(hue, saturation, value);
}
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Self::RGB { red, green, blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || saturation > 100 || value > 100 {
panic!("Invalid input");
}
Self::HSV { hue, saturation, value }
}
pub fn unwrap_rgb(&self) -> (u8, u8, u8) {
match *self {
Self::RGB { red, green, blue } => (red, green, blue),
_ => panic!("Това не е RGB!")
}
}
pub fn unwrap_hsv(&self) -> (u16, u8, u8) {
match *self {
Self::HSV { hue, saturation, value } => (hue, saturation, value),
_ => panic!("Това не е HSV!")
}
}
pub fn from_str(input: &str) -> Self {
let ch = input.chars().nth(0).unwrap();
if ch == '#' {
return <Color as Extract>::extract_rgb(input);
} else {
return <Color as Extract>::extract_hsv(input);
}
}
}
#[test]
fn test_rgb() {
let color1 = Color::from_str("#8064ff");
assert_eq!(color1.unwrap_rgb().0, 128);
assert_eq!(color1.unwrap_rgb().1, 100);
assert_eq!(color1.unwrap_rgb().2, 255);
let color2 = Color::from_str("#ffffff");
assert_eq!(color2.unwrap_rgb().0, 255);
assert_eq!(color2.unwrap_rgb().1, 255);
assert_eq!(color2.unwrap_rgb().2, 255);
let color3 = Color::from_str("#000000");
assert_eq!(color3.unwrap_rgb().0, 0);
assert_eq!(color3.unwrap_rgb().1, 0);
assert_eq!(color3.unwrap_rgb().2, 0);
let color4 = Color::from_str("#7f9b00");
assert_eq!(color4.unwrap_rgb().0, 127);
assert_eq!(color4.unwrap_rgb().1, 155);
assert_eq!(color4.unwrap_rgb().2, 0);
}
#[test]
fn test_hsv() {
let color1 = Color::from_str("hsv(0,0%,0%)");
assert_eq!(color1.unwrap_hsv().0, 0);
assert_eq!(color1.unwrap_hsv().1, 0);
assert_eq!(color1.unwrap_hsv().2, 0);
let color2 = Color::from_str("hsv(360,100%,100%)");
assert_eq!(color2.unwrap_hsv().0, 360);
assert_eq!(color2.unwrap_hsv().1, 100);
assert_eq!(color2.unwrap_hsv().2, 100);
let color3 = Color::from_str("hsv(220,100%,50%)");
assert_eq!(color3.unwrap_hsv().0, 220);
assert_eq!(color3.unwrap_hsv().1, 100);
assert_eq!(color3.unwrap_hsv().2, 50);
let color4 = Color::from_str("hsv(140,20%,70%)");
assert_eq!(color4.unwrap_hsv().0, 140);
assert_eq!(color4.unwrap_hsv().1, 20);
assert_eq!(color4.unwrap_hsv().2, 70);
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-1klpg4t/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.64s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hex_rgb ... ok
test solution_test::test_parsing_hsv ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Христо Георгиев
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Христо Георгиев

pub enum Color {
RGB {
red: u8,
green: u8,
blue: u8
},
HSV {
hue: u16,
saturation: u8,
value: u8,
}
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Color::RGB { red: red, green: green, blue: blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if 360 < hue {
panic! ("Hue is more than 360");
}
if 100 < saturation || value > 100{
panic! ("Saturation or Value are more than 100");
}
Color::HSV { hue: hue, saturation: saturation, value: value }
}
pub fn unwrap_rgb(&self) -> (u8, u8, u8) {
match &self {
Color::RGB{red, green, blue} => (*red, *green, *blue),
_ => panic! ("Object is no RGB type!"),
}
}
pub fn unwrap_hsv(&self) -> (u16, u8, u8) {
match &self {
Color::HSV {hue, saturation, value} => (*hue, *saturation, *value),
_ => panic! ("Object is no HSV type!"),
}
}
pub fn to_string(&self) -> String {
match &self {
Color::RGB {red, green, blue} => {
let mut str = String::from("#");
str.push_str(&format!("{:0>2x}" , red));
str.push_str(&format!("{:0>2x}", green));
str.push_str(&format!("{:0>2x}", blue));
return str;
},
Color::HSV {hue, saturation, value} => {
let mut str = String::from("hsv(");
str.push_str(&format!("{:?},", hue));
str.push_str(&format!("{:?}%,", saturation));
str.push_str(&format!("{:?}%)", value));
return str;
},
}
}
pub fn invert(&self) -> Self {
match &self {
Color::RGB {red, green, blue} => {
return Color::new_rgb(255 - red, 255 - green, 255-blue);
}
Color::HSV { hue, saturation, value } => {
return Color::new_hsv(360 - hue, 100 - saturation, 100 - value);
}
}
}
pub fn from_str(input: &str) -> Self {
let copy_of_str = input.clone();
if input.starts_with("hsv(") {
let (_hue_info, data) = copy_of_str.split_at(4);
let hue_index = data.find(',');
let (hue_buff, data_without_hue_and_coma) = &data.split_at(hue_index.unwrap());
let (coma1 , data_without_hue) = &data_without_hue_and_coma.split_at(1);
let saturation_index = data_without_hue.find('%');
let (saturation_buff , data_without_saturation_and_coma) = &data_without_hue.split_at(saturation_index.unwrap());
let (coma2, data_without_saturation) = &data_without_saturation_and_coma.split_at(2);
let value_index = data_without_saturation.find('%');
let (value_buff , _data_witout_value) = &data_without_saturation.split_at(value_index.unwrap());
Color::HSV { hue: hue_buff.parse().unwrap(), saturation: saturation_buff.parse().unwrap(), value: value_buff.parse().unwrap() }
}
else{
let (_ds, value) = copy_of_str.split_at(1);
let(red, green_and_blue) = value.split_at(2);
let(green, blue) = green_and_blue.split_at(2);
let red_buff = u8::from_str_radix(red, 16);
let green_buff = u8::from_str_radix(green, 16);
let blue_buff = u8::from_str_radix(blue, 16);
Color::RGB { red: red_buff.unwrap(), green: green_buff.unwrap(), blue: blue_buff.unwrap() }
}
}
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-x8mbhe/solution)
warning: unused variable: `coma1`
  --> src/lib.rs:81:18
   |
81 |             let (coma1 , data_without_hue) = &data_without_hue_and_coma.split_at(1);
   |                  ^^^^^ help: if this is intentional, prefix it with an underscore: `_coma1`
   |
   = note: `#[warn(unused_variables)]` on by default

warning: unused variable: `coma2`
  --> src/lib.rs:86:18
   |
86 |             let (coma2, data_without_saturation) = &data_without_saturation_and_coma.split_at(2);
   |                  ^^^^^ help: if this is intentional, prefix it with an underscore: `_coma2`

warning: `solution` (lib) generated 2 warnings
    Finished test [unoptimized + debuginfo] target(s) in 0.64s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hex_rgb ... ok
test solution_test::test_parsing_hsv ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Даниел Георгиев
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Даниел Георгиев

pub enum Color {
RGB {
red: u8,
green: u8,
blue: u8
},
HSV {
hue: u16,
saturation: u8,
value: u8,
}
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Self::RGB { red, green, blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || saturation > 100 || value > 100 {
panic!("Invalid input");
}
Self::HSV { hue, saturation, value }
}
fn from_str_rgb(input: &str) -> Option<Self> {
let mut characters = input.chars();
if characters.next().unwrap() != '#' {
return None;
}
let mut rgb : [u8; 3] = [0, 0, 0];
for i in 0..3 {
let mut num = String::new();
for _ in 0..2 {
let digit = match characters.next() {
Some(c) => c,
None => return None
};
num.push(digit);
}
let parse_res = u8::from_str_radix(num.as_str(), 16);
if let Ok(n) = parse_res {
rgb[i] = n;
} else {
return None;
}
}
if let Some(..) = characters.next() {
return None;
}
Some(Self::RGB {red: rgb[0], green: rgb[1], blue: rgb[2]})
}
fn from_str_hsv(input: &str) -> Option<Self> {
// Тази функция се получи зле, ама много ми се доспа
let mut characters = input.chars();
match characters.next() {
Some(c) if c != 'h' => return None,
None => return None,
_ => ()
};
match characters.next() {
Some(c) if c != 's' => return None,
None => return None,
_ => ()
};
match characters.next() {
Some(c) if c != 'v' => return None,
None => return None,
_ => ()
};
match characters.next() {
Some(c) if c != '(' => return None,
None => return None,
_ => ()
};
let mut num = String::new();
let mut last : char;
loop {
last = match characters.next() {
Some(c) => c,
None => return None,
};
if last.is_digit(10) {
num.push(last)
} else {
break;
}
};
if last != ',' {
return None;
}
if num.is_empty() {
return None;
}
let hue: u16;
let parse_res = u16::from_str_radix(num.as_str(), 10);
if let Ok(n) = parse_res {
hue = n;
if hue > 360 {
return None;
}
} else {
return None;
}
let mut num = String::new();
let mut last : char;
loop {
last = match characters.next() {
Some(c) => c,
None => return None,
};
if last.is_digit(10) {
num.push(last)
} else {
break;
}
};
if last != '%' {
return None;
}
if num.is_empty() {
return None;
}
let saturation : u8;
let parse_res = u8::from_str_radix(num.as_str(), 10);
if let Ok(n) = parse_res {
saturation = n;
if saturation > 100 {
return None;
}
} else {
return None;
}
match characters.next() {
Some(c) if c != ',' => return None,
None => return None,
_ => ()
};
let mut num = String::new();
let mut last : char;
loop {
last = match characters.next() {
Some(c) => c,
None => return None,
};
if last.is_digit(10) {
num.push(last)
} else {
break;
}
};
if last != '%' {
return None;
}
if num.is_empty() {
return None;
}
let value : u8;
let parse_res = u8::from_str_radix(num.as_str(), 10);
if let Ok(n) = parse_res {
value = n;
if value > 100 {
return None;
}
} else {
return None;
}
match characters.next() {
Some(c) if c != ')' => return None,
None => return None,
_ => ()
};
if let Some(..) = characters.next() {
return None;
}
Some(Self::HSV {hue, saturation, value} )
}
pub fn from_str(input: &str) -> Self {
let res = Self::from_str_rgb(input);
if let Some(rgb_color) = res {
return rgb_color;
}
let res = Self::from_str_hsv(input);
if let Some(hsv_color) = res {
hsv_color
} else {
panic!("Cannot find a conversion from \"{}\" to Color", input)
}
}
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-60dsis/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.62s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hex_rgb ... ok
test solution_test::test_parsing_hsv ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Христо Вълев
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Христо Вълев

pub enum Color {
RGB {
red: u8,
green: u8,
blue: u8,
},
HSV {
hue: u16,
saturation: u8,
value: u8,
},
}
pub fn char_to_u8(char1: char) -> u8 {
let num1: u8 = match char1 {
'0' => 0,
'1' => 1,
'2' => 2,
'3' => 3,
'4' => 4,
'5' => 5,
'6' => 6,
'7' => 7,
'8' => 8,
'9' => 9,
'a' => 10,
'b' => 11,
'c' => 12,
'd' => 13,
'e' => 14,
'f' => 15,
_ => panic!("Invalid symbol!!!"),
};
return num1;
}
pub fn hex_to_dec(char1: char, char2: char) -> u8 {
let num1: u8 = char_to_u8(char1);
let num2: u8 = char_to_u8(char2);
let result = num1 * 16 + num2;
return result;
}
pub fn pow_u16(num: u16, pow: i16) -> u16 {
let mut result: u16 = 1;
let mut pow_copy = pow;
while pow_copy > 0
{
result = result * num;
pow_copy = pow_copy - 1;
}
return result;
}
pub fn string_to_u16(string: &str, size: usize) -> u16 {
let mut i = 0;
let mut power = (size - 1) as i16;
let mut result: u16 = 0;
while i < size
{
result = result + (char_to_u8(string.chars().nth(i).unwrap()) as u16) * pow_u16(10, power);
power = power - 1;
i = i + 1;
}
return result;
}
pub fn hsv_string_to_tuple(input: &str) -> (u16, u16, u16) {
let mut separators = 0;
let mut hue = String::from("");
let mut saturation = String::from("");
let mut value = String::from("");
for c in input[4..].chars()
{
if separators == 0 && c != ',' && c != '%' && c != ')' {
hue.push(c);
} else if separators == 1 && c != ',' && c != '%' && c != ')' {
saturation.push(c);
} else if separators == 2 && c != ',' && c != '%' && c != ')' {
value.push(c);
}
if c == ',' {
separators = separators + 1;
}
}
return (string_to_u16(&hue, hue.len()), string_to_u16(&saturation, saturation.len()), string_to_u16(&value, value.len()));
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Self::RGB { red, green, blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || saturation > 100 || value > 100 {
panic!("Invalid input");
}
Self::HSV { hue, saturation, value }
}
pub fn from_str(input: &str) -> Self {
let result: Color;
if input.chars().next().unwrap() == '#' {
result = Color::new_rgb(hex_to_dec(input.chars().nth(1).unwrap(), input.chars().nth(2).unwrap()), hex_to_dec(input.chars().nth(3).unwrap(), input.chars().nth(4).unwrap()), hex_to_dec(input.chars().nth(5).unwrap(), input.chars().nth(6).unwrap()));
} else if input.chars().next().unwrap() == 'h' {
result = Color::HSV { hue: hsv_string_to_tuple(input).0, saturation: hsv_string_to_tuple(input).1 as u8, value: hsv_string_to_tuple(input).2 as u8 };
} else { panic!("Invalid input"); }
return result;
}
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-1mba4t2/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.62s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hex_rgb ... ok
test solution_test::test_parsing_hsv ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Теодор Кирилов
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Теодор Кирилов

use std::u8;//за да може да ползваме u8::from_str_radix()
pub enum Color {
RGB {
red: u8,
green: u8,
blue: u8
},
HSV {
hue: u16,
saturation: u8,
value: u8,
}
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Self::RGB { red, green, blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || saturation > 100 || value > 100 {
panic!("Invalid input");
}
Self::HSV { hue, saturation, value }
}
pub fn from_str(input: &str) -> Self {
let first_character=&input[0..1];
match first_character {
//ако стринга започва с h значи е hsv(x,x%,x%)
"h" => {
let last_el_index=input.len();
let substr=&input[4..last_el_index-1];
let v: Vec<&str> = substr.splitn(3, ',').collect();
let hue:u16=v[0].parse::<u16>().unwrap();
let s_without_percent=&v[1][0..v[1].len()-1];
let saturation:u8=s_without_percent.parse::<u8>().unwrap();
let v_without_percent=&v[2][0..v[2].len()-1];
let value:u8=v_without_percent.parse::<u8>().unwrap();
Color::new_hsv(hue,saturation,value)
}
//ако стринга започва с # значи е rgb #xxxxxx
"#" =>{
let v = vec![&input[1..3], &input[3..5], &input[5..7]];
let red=u8::from_str_radix(v[0],16).unwrap();
let green=u8::from_str_radix(v[1],16).unwrap();
let blue=u8::from_str_radix(v[2],16).unwrap();
Color::new_rgb(red, green, blue)
}
_ => panic!("Invalid format!")//idk what the message should be
}
}
}
//За тестовете си добавих unwrap функциите :Д
impl Color {
pub fn unwrap_rgb(&self) -> (u8, u8, u8) {
match self{
Color::RGB{red, green, blue}=>(*red,*green,*blue),
_ =>panic!("Expected RGB, not HSV!"),
}
}
pub fn unwrap_hsv(&self) -> (u16, u8, u8) {
match self{
Color::HSV { hue, saturation, value } => (*hue,*saturation,*value),
_ => panic!("Expected HSV! "),
}
}
}
//testing from_str() function for HSV
#[test]
fn test1() {
let c:Color=Color::from_str("hsv(200,5%,20%)");
assert_eq!(c.unwrap_hsv(), (200,5,20));
}
#[test]
fn test2() {
let c:Color=Color::from_str("hsv(0,0%,0%)");
assert_eq!(c.unwrap_hsv(), (0,0,0));
}
#[test]
fn test3() {
let c:Color=Color::from_str("hsv(360,100%,100%)");
assert_eq!(c.unwrap_hsv(), (360,100,100));
}
#[test]
#[should_panic]
fn test4() {
Color::from_str("hsv(361,0%,0%)");
}
#[test]
#[should_panic]
fn test5() {
Color::from_str("hsv(360,101%,0%)");
}
#[test]
#[should_panic]
fn test6() {
Color::from_str("hsv(360,0%,101%)");
}
//testing from_str() function for RGB
#[test]
fn test7() {
let c:Color=Color::from_str("#ffffff");
assert_eq!(c.unwrap_rgb(), (255,255,255));
}
#[test]
fn test8() {
let c:Color=Color::from_str("#000000");
assert_eq!(c.unwrap_rgb(), (0,0,0));
}
#[test]
fn test9() {
let c:Color=Color::from_str("#000100");
assert_eq!(c.unwrap_rgb(), (0,1,0));
}
#[test]
fn test10() {
let c:Color=Color::from_str("#abcdef");
assert_eq!(c.unwrap_rgb(), (171,205,239));
}
#[test]
#[should_panic]
//казано ни е, че входа е коректен, но все пак да си тествам default case-а на match в from_str()
fn test11() {
Color::from_str("🙂");
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-1wy61q6/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.64s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hex_rgb ... ok
test solution_test::test_parsing_hsv ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Кристиян Войнски
  • Некоректно
  • 1 успешни тест(а)
  • 1 неуспешни тест(а)
Кристиян Войнски

pub enum Color {
RGB {
red: u8,
green: u8,
blue: u8,
},
HSV {
hue: u16,
saturation: u8,
value: u8,
},
}
impl Color {
pub fn new_rgb(red: u8, green: u8, blue: u8) -> Color {
Self::RGB { red, green, blue }
}
pub fn new_hsv(hue: u16, saturation: u8, value: u8) -> Color {
if hue > 360 || saturation > 100 || value > 100 {
panic!("Invalid input");
}
Self::HSV { hue, saturation, value }
}
pub fn from_str(input: &str) -> Self {
if input.starts_with('#') {
return Color::RGB {
red: u8::from_str_radix(&input[1..3], 16).unwrap(),
green: u8::from_str_radix(&input[3..5], 16).unwrap(),
blue: u8::from_str_radix(&input[1..3], 16).unwrap(),
};
}
if input.starts_with("hsv") {
let (hue_str, other) = input
.strip_prefix("hsv(")
.and_then(|s| s.strip_suffix(')'))
.and_then(|s| s.split_once(','))
.unwrap();
let (saturation_str, value_str) = other
.strip_suffix('%')
.and_then(|s| s.split_once("%,"))
.unwrap();
let hue = u16::from_str_radix(hue_str, 10).unwrap();
let saturation = u8::from_str_radix(saturation_str, 10).unwrap();
let value = u8::from_str_radix(value_str, 10).unwrap();
if hue > 360 || saturation > 100 || value > 100 {
panic!("Correct values hue <= 360, saturation <= 100, value <= 100")
}
return Color::HSV { hue, saturation, value };
}
panic!("invalid input")
}
}
Compiling solution v0.1.0 (/tmp/d20221103-1221210-1ber1ab/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.60s
     Running tests/solution_test.rs (target/debug/deps/solution_test-867d7317a91c4f07)

running 2 tests
test solution_test::test_parsing_hsv ... ok
test solution_test::test_parsing_hex_rgb ... FAILED

failures:

---- solution_test::test_parsing_hex_rgb stdout ----
thread 'solution_test::test_parsing_hex_rgb' panicked at 'assertion failed: `(left == right)`
  left: `171`,
 right: `239`', tests/solution_test.rs:24:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    solution_test::test_parsing_hex_rgb

test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

error: test failed, to rerun pass '--test solution_test'
Петър Атанасов
  • Коректно
  • 2 успешни тест(а)
  • 0 неуспешни тест(а)
Петър Атанасов

use std::str::FromStr;
pub enum Color {