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