git_bug/entities/issue/data/
label.rs1use std::fmt::Display;
15
16use serde::{Deserialize, Serialize};
17use sha2::{Digest, Sha256};
18use simd_json::{borrowed, derived::ValueTryIntoString, owned};
19
20#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize)]
24pub struct Label(pub(crate) String);
25
26impl From<&str> for Label {
27 fn from(value: &str) -> Self {
28 Self(value.to_owned())
29 }
30}
31
32impl TryFrom<owned::Value> for Label {
33 type Error = value_parse::Error;
34
35 fn try_from(value: owned::Value) -> Result<Self, Self::Error> {
36 let string = value
37 .try_into_string()
38 .map_err(|err| value_parse::Error::StrExpected { err })?;
39
40 Ok(Self(string))
41 }
42}
43
44impl<'a> From<&'a Label> for borrowed::Value<'a> {
45 fn from(val: &'a Label) -> Self {
46 borrowed::Value::String(std::borrow::Cow::Borrowed(&val.0))
47 }
48}
49
50#[allow(missing_docs)]
51pub mod value_parse {
52 #[derive(Debug, thiserror::Error)]
53 pub enum Error {
54 #[error("Expected string in json data, but found something else: {err}")]
55 StrExpected { err: simd_json::TryTypeError },
56 }
57}
58
59impl Display for Label {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 self.0.fmt(f)
62 }
63}
64
65impl Label {
66 #[must_use]
69 pub fn associate_color(&self) -> Color {
70 let colors = [
72 Color::from_rgba(244, 67, 54, 255), Color::from_rgba(233, 30, 99, 255), Color::from_rgba(156, 39, 176, 255), Color::from_rgba(103, 58, 183, 255), Color::from_rgba(63, 81, 181, 255), Color::from_rgba(33, 150, 243, 255), Color::from_rgba(3, 169, 244, 255), Color::from_rgba(0, 188, 212, 255), Color::from_rgba(0, 150, 136, 255), Color::from_rgba(76, 175, 80, 255), Color::from_rgba(139, 195, 74, 255), Color::from_rgba(205, 220, 57, 255), Color::from_rgba(255, 235, 59, 255), Color::from_rgba(255, 193, 7, 255), Color::from_rgba(255, 152, 0, 255), Color::from_rgba(255, 87, 34, 255), Color::from_rgba(121, 85, 72, 255), Color::from_rgba(158, 158, 158, 255), Color::from_rgba(96, 125, 139, 255), ];
92
93 let hash = Sha256::digest(self.to_string().as_bytes());
94
95 let id: usize = hash
96 .into_iter()
97 .map(|val| val as usize)
98 .fold(0, |acc, val| (acc + val) % colors.len());
99
100 colors[id]
101 }
102}
103
104#[derive(Default, Clone, Copy, Debug)]
105pub struct Color {
110 pub red: u8,
112
113 pub green: u8,
115
116 pub blue: u8,
118
119 pub alpha: u8,
121}
122
123impl Color {
124 #[must_use]
126 pub fn from_rgba(red: u8, green: u8, blue: u8, alpha: u8) -> Self {
127 Self {
128 red,
129 green,
130 blue,
131 alpha,
132 }
133 }
134}