splinter_rs/
level.rs

1use std::{
2    fmt::{Debug, Display},
3    ops::{BitAndAssign, BitOrAssign, BitXorAssign, SubAssign},
4};
5
6use ::u24::U24;
7use num::{
8    cast::AsPrimitive,
9    traits::{ConstOne, ConstZero},
10};
11use u24::u24;
12use zerocopy::{BE, FromBytes, Immutable, IntoBytes, KnownLayout, U16, U32, Unaligned};
13
14use crate::{
15    codec::{Encodable, partition_ref::PartitionRef},
16    never::Never,
17    partition::Partition,
18    segment::SplitSegment,
19    traits::{
20        Complement, Cut, DefaultFull, Optimizable, PartitionRead, PartitionWrite, TruncateFrom,
21    },
22};
23
24#[doc(hidden)]
25pub trait Level: Sized + Clone + Copy {
26    const DEBUG_NAME: &'static str;
27
28    type LevelDown: Level;
29
30    type Down: PartitionRead<Self::LevelDown>
31        + PartitionWrite<Self::LevelDown>
32        + Optimizable
33        + Encodable
34        + Default
35        + DefaultFull
36        + Debug
37        + Clone
38        + Eq
39        + PartialEq
40        + Complement
41        + Cut<Out = Self::Down>
42        + for<'a> Cut<PartitionRef<'a, Self::LevelDown>, Out = Self::Down>
43        + for<'a> PartialEq<PartitionRef<'a, Self::LevelDown>>
44        + for<'a> BitOrAssign<&'a Self::Down>
45        + for<'a> BitOrAssign<&'a PartitionRef<'a, Self::LevelDown>>
46        + for<'a> BitAndAssign<&'a Self::Down>
47        + for<'a> BitAndAssign<&'a PartitionRef<'a, Self::LevelDown>>
48        + for<'a> BitXorAssign<&'a Self::Down>
49        + for<'a> BitXorAssign<&'a PartitionRef<'a, Self::LevelDown>>
50        + for<'a> SubAssign<&'a Self::Down>
51        + for<'a> SubAssign<&'a PartitionRef<'a, Self::LevelDown>>
52        + for<'a> From<&'a PartitionRef<'a, Self::LevelDown>>;
53
54    type Value: num::PrimInt
55        + AsPrimitive<usize>
56        + SplitSegment<Rest = <Self::LevelDown as Level>::Value>
57        + TruncateFrom<usize>
58        + ConstZero
59        + ConstOne
60        + Debug
61        + Display
62        + Clone
63        + range_set_blaze::Integer;
64
65    type ValueUnaligned: IntoBytes
66        + FromBytes
67        + Unaligned
68        + Immutable
69        + KnownLayout
70        + Into<Self::Value>
71        + From<Self::Value>
72        + Ord
73        + Debug
74        + Display
75        + Copy;
76
77    const BITS: usize;
78    const MAX_LEN: usize = 1 << Self::BITS;
79    const ALLOW_TREE: bool = Self::BITS > 8;
80}
81
82/// High is an internal type which is only exposed in docs due to it's usage in
83/// the `PartitionRead` trait.
84#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
85pub struct High;
86
87impl Level for High {
88    const DEBUG_NAME: &'static str = "High";
89
90    type LevelDown = Mid;
91    type Down = Partition<Self::LevelDown>;
92    type Value = u32;
93    type ValueUnaligned = U32<BE>;
94
95    const BITS: usize = 32;
96}
97
98#[doc(hidden)]
99#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
100pub struct Mid;
101
102impl Level for Mid {
103    const DEBUG_NAME: &'static str = "Mid";
104
105    type LevelDown = Low;
106    type Down = Partition<Self::LevelDown>;
107    type Value = u24;
108    type ValueUnaligned = U24<BE>;
109
110    const BITS: usize = 24;
111}
112
113#[doc(hidden)]
114#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
115pub struct Low;
116
117impl Level for Low {
118    const DEBUG_NAME: &'static str = "Low";
119
120    type LevelDown = Block;
121    type Down = Partition<Self::LevelDown>;
122    type Value = u16;
123    type ValueUnaligned = U16<BE>;
124
125    const BITS: usize = 16;
126}
127
128#[doc(hidden)]
129#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
130pub struct Block;
131
132impl Level for Block {
133    const DEBUG_NAME: &'static str = "Block";
134
135    type LevelDown = Never;
136    type Down = Never;
137    type Value = u8;
138    type ValueUnaligned = u8;
139
140    const BITS: usize = 8;
141}