(value: &str)
| 536 | } |
| 537 | |
| 538 | fn parse_color_literal(value: &str) -> Option<Color> { |
| 539 | let lowered = value.trim().to_ascii_lowercase(); |
| 540 | if lowered == "transparent" || lowered == "none" { |
| 541 | return Some(Color::Reset); |
| 542 | } |
| 543 | |
| 544 | let hex = lowered.strip_prefix('#')?; |
| 545 | match hex.len() { |
| 546 | 3 => { |
| 547 | let r = parse_hex_nibble(hex.as_bytes()[0])?; |
| 548 | let g = parse_hex_nibble(hex.as_bytes()[1])?; |
| 549 | let b = parse_hex_nibble(hex.as_bytes()[2])?; |
| 550 | Some(Color::Rgb(r * 17, g * 17, b * 17)) |
| 551 | } |
| 552 | 4 => { |
| 553 | let r = parse_hex_nibble(hex.as_bytes()[0])?; |
| 554 | let g = parse_hex_nibble(hex.as_bytes()[1])?; |
| 555 | let b = parse_hex_nibble(hex.as_bytes()[2])?; |
| 556 | let a = parse_hex_nibble(hex.as_bytes()[3])?; |
| 557 | if a == 0 { |
| 558 | Some(Color::Reset) |
| 559 | } else { |
| 560 | Some(Color::Rgb(r * 17, g * 17, b * 17)) |
| 561 | } |
| 562 | } |
| 563 | 6 => { |
| 564 | let bytes = hex.as_bytes(); |
| 565 | let r = parse_hex_byte(bytes[0], bytes[1])?; |
| 566 | let g = parse_hex_byte(bytes[2], bytes[3])?; |
| 567 | let b = parse_hex_byte(bytes[4], bytes[5])?; |
| 568 | Some(Color::Rgb(r, g, b)) |
| 569 | } |
| 570 | 8 => { |
| 571 | let bytes = hex.as_bytes(); |
| 572 | let r = parse_hex_byte(bytes[0], bytes[1])?; |
| 573 | let g = parse_hex_byte(bytes[2], bytes[3])?; |
| 574 | let b = parse_hex_byte(bytes[4], bytes[5])?; |
| 575 | let a = parse_hex_byte(bytes[6], bytes[7])?; |
| 576 | if a == 0 { |
| 577 | Some(Color::Reset) |
| 578 | } else { |
| 579 | Some(Color::Rgb(r, g, b)) |
| 580 | } |
| 581 | } |
| 582 | _ => None, |
| 583 | } |
| 584 | } |
| 585 | |
| 586 | fn parse_hex_nibble(c: u8) -> Option<u8> { |
| 587 | match c { |
no test coverage detected