1use std::ops::Deref;
2
3use enumflags2::BitFlags;
4
5#[enumflags2::bitflags]
7#[repr(u8)]
8#[derive(Copy, Clone, PartialEq)]
9pub enum DataKind {
10 Bytes = 1 << 0,
11 Str = 1 << 1,
12 Parsed = 1 << 2,
13}
14impl DataKind {
15 pub(crate) const fn count() -> usize {
16 <BitFlags<DataKind>>::ALL.bits_c().count_ones() as usize
17 }
18}
19#[repr(transparent)]
20pub struct DataKinds(BitFlags<DataKind>);
21impl DataKinds {
22 pub const fn from_slice(s: &[DataKind]) -> Self {
23 let mut i = 0;
24 let mut res = BitFlags::EMPTY;
25 while i < s.len() {
26 let item: BitFlags<DataKind, u8> =
27 BitFlags::<DataKind, u8>::from_bits_truncate_c(s[i] as u8, BitFlags::CONST_TOKEN);
28 res = BitFlags::<DataKind, u8>::union_c(res, item);
29 i += 1;
30 }
31 Self(res)
32 }
33}
34impl Deref for DataKinds {
35 type Target = BitFlags<DataKind>;
36
37 fn deref(&self) -> &Self::Target {
38 &self.0
39 }
40}
41
42pub struct DataKindPreference {
44 ordering: [Option<DataKind>; DataKind::count()],
46}
47impl DataKindPreference {
48 pub const BYTES_PREF: Self =
49 Self::from_slice(&[DataKind::Bytes, DataKind::Str, DataKind::Parsed]);
50
51 pub const PARSED_PREF: Self =
52 Self::from_slice(&[DataKind::Parsed, DataKind::Str, DataKind::Bytes]);
53
54 pub const STR_PREF: Self =
55 Self::from_slice(&[DataKind::Str, DataKind::Bytes, DataKind::Parsed]);
56
57 pub const fn from_slice(ordering_slice: &[DataKind]) -> Self {
58 let mut ordering = [None; DataKind::count()];
59 let mut i = 0;
60 while i < ordering.len() && i < ordering_slice.len() {
61 ordering[i] = Some(ordering_slice[i]);
62 i += 1;
63 }
64
65 Self { ordering }
66 }
67
68 pub const fn top(&self, provided: DataKinds) -> Option<DataKind> {
69 let mut i = 0;
70 while i < self.ordering.len() {
71 if let Some(item) = self.ordering[i] {
72 let bf_item =
73 BitFlags::<_, u8>::from_bits_truncate_c(item as u8, BitFlags::CONST_TOKEN);
74 let contained = provided.0.intersection_c(bf_item).bits_c() == 0;
75 if contained {
76 return Some(item);
77 }
78 }
79 i += 1;
80 }
81
82 None
83 }
84}