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        + Extend<<Self::LevelDown as Level>::Value>
42        + Cut<Out = Self::Down>
43        + From<Partition<Self::LevelDown>>
44        + for<'a> Cut<PartitionRef<'a, Self::LevelDown>, Out = Self::Down>
45        + for<'a> PartialEq<PartitionRef<'a, Self::LevelDown>>
46        + for<'a> BitOrAssign<&'a Self::Down>
47        + for<'a> BitOrAssign<&'a PartitionRef<'a, Self::LevelDown>>
48        + for<'a> BitAndAssign<&'a Self::Down>
49        + for<'a> BitAndAssign<&'a PartitionRef<'a, Self::LevelDown>>
50        + for<'a> BitXorAssign<&'a Self::Down>
51        + for<'a> BitXorAssign<&'a PartitionRef<'a, Self::LevelDown>>
52        + for<'a> SubAssign<&'a Self::Down>
53        + for<'a> SubAssign<&'a PartitionRef<'a, Self::LevelDown>>
54        + for<'a> From<&'a PartitionRef<'a, Self::LevelDown>>;
55
56    type Value: num::PrimInt
57        + AsPrimitive<usize>
58        + SplitSegment<Rest = <Self::LevelDown as Level>::Value>
59        + TruncateFrom<usize>
60        + ConstZero
61        + ConstOne
62        + Debug
63        + Display
64        + Clone
65        + range_set_blaze::Integer;
66
67    type ValueUnaligned: IntoBytes
68        + FromBytes
69        + Unaligned
70        + Immutable
71        + KnownLayout
72        + Into<Self::Value>
73        + From<Self::Value>
74        + Ord
75        + Debug
76        + Display
77        + Copy;
78
79    const BITS: usize;
80    const MAX_LEN: usize = 1 << Self::BITS;
81    const ALLOW_TREE: bool = Self::BITS > 8;
82}
83
84/// High is an internal type which is only exposed in docs due to it's usage in
85/// the `PartitionRead` trait.
86#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
87pub struct High;
88
89impl Level for High {
90    const DEBUG_NAME: &'static str = "High";
91
92    type LevelDown = Mid;
93    type Down = Partition<Self::LevelDown>;
94    type Value = u32;
95    type ValueUnaligned = U32<BE>;
96
97    const BITS: usize = 32;
98}
99
100#[doc(hidden)]
101#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
102pub struct Mid;
103
104impl Level for Mid {
105    const DEBUG_NAME: &'static str = "Mid";
106
107    type LevelDown = Low;
108    type Down = Partition<Self::LevelDown>;
109    type Value = u24;
110    type ValueUnaligned = U24<BE>;
111
112    const BITS: usize = 24;
113}
114
115#[doc(hidden)]
116#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
117pub struct Low;
118
119impl Level for Low {
120    const DEBUG_NAME: &'static str = "Low";
121
122    type LevelDown = Block;
123    type Down = Partition<Self::LevelDown>;
124    type Value = u16;
125    type ValueUnaligned = U16<BE>;
126
127    const BITS: usize = 16;
128}
129
130#[doc(hidden)]
131#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
132pub struct Block;
133
134impl Level for Block {
135    const DEBUG_NAME: &'static str = "Block";
136
137    type LevelDown = Never;
138    type Down = Never;
139    type Value = u8;
140    type ValueUnaligned = u8;
141
142    const BITS: usize = 8;
143}