1use crate::Rgba;
2
3pub const EMPTY_SET: Sympols = Sympols::new(vec![]);
5
6pub const EMPTY_CHAR: char = ' ';
8
9#[derive(Debug, PartialEq, PartialOrd, Clone, Hash)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub struct Sympols {
13 set: Vec<char>,
14}
15
16impl Sympols {
17 pub const fn new(set: Vec<char>) -> Sympols {
19 Sympols { set }
20 }
21
22 pub const fn empty() -> Self {
24 EMPTY_SET
25 }
26
27 #[inline(always)]
29 pub fn get(&self, i: usize) -> char {
30 if self.is_empty() {
31 return EMPTY_CHAR;
32 }
33 self.set[i]
34 }
35
36 #[inline(always)]
38 pub fn len(&self) -> usize {
39 self.set.len()
40 }
41
42 #[inline(always)]
44 pub fn is_empty(&self) -> bool {
45 self.set.is_empty()
46 }
47
48 #[inline]
50 pub(crate) fn sym_index(&self, pixel: &Rgba) -> usize {
51 if self.is_empty() {
52 return 0;
53 }
54 let len = self.len();
55 let mut idx = (pixel.r as usize + pixel.g as usize + pixel.b as usize) / 3;
57
58 if idx == 0 {
59 return 0;
60 }
61
62 if pixel.a < 120 {
63 idx = pixel.a as usize % idx;
64 }
65
66 idx /= 255 / len;
68 if idx >= len {
69 return len - 1;
70 }
71 idx
72 }
73
74 #[inline]
76 pub(crate) fn sym_and_index(&self, pixel: &Rgba) -> (char, usize) {
77 let idx = self.sym_index(pixel);
78 (self.get(idx), idx)
79 }
80}
81
82impl From<&[char]> for Sympols {
83 fn from(value: &[char]) -> Self {
84 Self::new(value.into())
85 }
86}
87
88impl From<Vec<char>> for Sympols {
89 fn from(value: Vec<char>) -> Self {
90 Self::new(value)
91 }
92}