climeta/core/
columns.rs

1use byteorder::{ByteOrder, LittleEndian};
2
3use super::db::TableDesc;
4
5pub(crate) trait ColumnIndex { fn idx() -> usize; }
6
7pub(crate) struct Col0;
8impl ColumnIndex for Col0 { fn idx() -> usize { 0 } }
9pub(crate) struct Col1;
10impl ColumnIndex for Col1 { fn idx() -> usize { 1 } }
11pub(crate) struct Col2;
12impl ColumnIndex for Col2 { fn idx() -> usize { 2 } }
13pub(crate) struct Col3;
14impl ColumnIndex for Col3 { fn idx() -> usize { 3 } }
15pub(crate) struct Col4;
16impl ColumnIndex for Col4 { fn idx() -> usize { 4 } }
17pub(crate) struct Col5;
18impl ColumnIndex for Col5 { fn idx() -> usize { 5 } }
19
20pub(crate) trait ColumnTuple: Copy {
21    fn row_size(&self) -> u8;
22    fn init(&self, cols: &mut [Column]);
23}
24
25pub(crate) trait ColumnTupleAccess<Col: ColumnIndex>: ColumnTuple {
26    type Out: ColumnSize;
27}
28
29impl<C0: ColumnSize> ColumnTuple for (C0,) {
30    fn row_size(&self) -> u8 { self.0.size() }
31    fn init(&self, cols: &mut [Column]) { cols[0] = Column { offset: 0, size: self.0.size() }; }
32}
33impl<C0: ColumnSize> ColumnTupleAccess<Col0> for (C0,) { type Out = C0; }
34
35impl<C0: ColumnSize, C1: ColumnSize> ColumnTuple for (C0, C1) {
36    fn row_size(&self) -> u8 { self.0.size() + self.1.size() }
37    fn init(&self, cols: &mut [Column]) { (self.0,).init(cols); cols[1] = Column { offset: cols[0].offset + cols[0].size, size: self.1.size() }; }
38}
39impl<C0: ColumnSize, C1: ColumnSize> ColumnTupleAccess<Col0> for (C0, C1) { type Out = C0; }
40impl<C0: ColumnSize, C1: ColumnSize> ColumnTupleAccess<Col1> for (C0, C1) { type Out = C1; }
41
42impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize> ColumnTuple for (C0, C1, C2) {
43    fn row_size(&self) -> u8 { self.0.size() + self.1.size() + self.2.size() }
44    fn init(&self, cols: &mut [Column]) { (self.0, self.1).init(cols); cols[2] = Column { offset: cols[1].offset + cols[1].size, size: self.2.size() }; }
45}
46impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize> ColumnTupleAccess<Col0> for (C0, C1, C2) { type Out = C0; }
47impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize> ColumnTupleAccess<Col1> for (C0, C1, C2) { type Out = C1; }
48impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize> ColumnTupleAccess<Col2> for (C0, C1, C2) { type Out = C2; }
49
50impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize, C3: ColumnSize> ColumnTuple for (C0, C1, C2, C3) {
51    fn row_size(&self) -> u8 { self.0.size() + self.1.size() + self.2.size() + self.3.size() }
52    fn init(&self, cols: &mut [Column]) { (self.0, self.1, self.2).init(cols); cols[3] = Column { offset: cols[2].offset + cols[2].size, size: self.3.size() }; }
53}
54impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize, C3: ColumnSize> ColumnTupleAccess<Col0> for (C0, C1, C2, C3) { type Out = C0; }
55impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize, C3: ColumnSize> ColumnTupleAccess<Col1> for (C0, C1, C2, C3) { type Out = C1; }
56impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize, C3: ColumnSize> ColumnTupleAccess<Col2> for (C0, C1, C2, C3) { type Out = C2; }
57impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize, C3: ColumnSize> ColumnTupleAccess<Col3> for (C0, C1, C2, C3) { type Out = C3; }
58
59impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize, C3: ColumnSize, C4: ColumnSize> ColumnTuple for (C0, C1, C2, C3, C4) {
60    fn row_size(&self) -> u8 { self.0.size() + self.1.size() + self.2.size() + self.3.size() + self.4.size() }
61    fn init(&self, cols: &mut [Column]) { (self.0, self.1, self.2, self.3).init(cols); cols[4] = Column { offset: cols[3].offset + cols[3].size, size: self.4.size() }; }
62}
63impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize, C3: ColumnSize, C4: ColumnSize> ColumnTupleAccess<Col0> for (C0, C1, C2, C3, C4) { type Out = C0; }
64impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize, C3: ColumnSize, C4: ColumnSize> ColumnTupleAccess<Col1> for (C0, C1, C2, C3, C4) { type Out = C1; }
65impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize, C3: ColumnSize, C4: ColumnSize> ColumnTupleAccess<Col2> for (C0, C1, C2, C3, C4) { type Out = C2; }
66impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize, C3: ColumnSize, C4: ColumnSize> ColumnTupleAccess<Col3> for (C0, C1, C2, C3, C4) { type Out = C3; }
67impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize, C3: ColumnSize, C4: ColumnSize> ColumnTupleAccess<Col4> for (C0, C1, C2, C3, C4) { type Out = C4; }
68
69impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize, C3: ColumnSize, C4: ColumnSize, C5: ColumnSize> ColumnTuple for (C0, C1, C2, C3, C4, C5) {
70    fn row_size(&self) -> u8 { self.0.size() + self.1.size() + self.2.size() + self.3.size() + self.4.size() + self.5.size() }
71    fn init(&self, cols: &mut [Column]) { (self.0, self.1, self.2, self.3, self.4).init(cols); cols[5] = Column { offset: cols[4].offset + cols[4].size, size: self.5.size() }; }
72}
73impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize, C3: ColumnSize, C4: ColumnSize, C5: ColumnSize> ColumnTupleAccess<Col0> for (C0, C1, C2, C3, C4, C5) { type Out = C0; }
74impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize, C3: ColumnSize, C4: ColumnSize, C5: ColumnSize> ColumnTupleAccess<Col1> for (C0, C1, C2, C3, C4, C5) { type Out = C1; }
75impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize, C3: ColumnSize, C4: ColumnSize, C5: ColumnSize> ColumnTupleAccess<Col2> for (C0, C1, C2, C3, C4, C5) { type Out = C2; }
76impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize, C3: ColumnSize, C4: ColumnSize, C5: ColumnSize> ColumnTupleAccess<Col3> for (C0, C1, C2, C3, C4, C5) { type Out = C3; }
77impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize, C3: ColumnSize, C4: ColumnSize, C5: ColumnSize> ColumnTupleAccess<Col4> for (C0, C1, C2, C3, C4, C5) { type Out = C4; }
78impl<C0: ColumnSize, C1: ColumnSize, C2: ColumnSize, C3: ColumnSize, C4: ColumnSize, C5: ColumnSize> ColumnTupleAccess<Col5> for (C0, C1, C2, C3, C4, C5) { type Out = C5; }
79
80pub(crate) trait ColumnSize: Copy {
81    fn size(&self) -> u8;
82}
83
84#[derive(Copy, Clone, Default)]
85pub(crate) struct FixedSize2;
86impl ColumnSize for FixedSize2 {
87    fn size(&self) -> u8 { 2 }
88}
89
90#[derive(Copy, Clone, Default)]
91pub(crate) struct FixedSize4;
92impl ColumnSize for FixedSize4 {
93    fn size(&self) -> u8 { 4 }
94}
95
96#[derive(Copy, Clone, Default)]
97pub(crate) struct FixedSize8;
98impl ColumnSize for FixedSize8 {
99    fn size(&self) -> u8 { 8 }
100}
101
102#[derive(Copy, Clone, Debug)]
103pub(crate) enum DynamicSize {
104    Unset,
105    Size2,
106    Size4
107}
108
109impl ColumnSize for DynamicSize {
110    fn size(&self) -> u8 {
111        match *self {
112            DynamicSize::Unset => panic!("uninitialized dynamic column"),
113            DynamicSize::Size2 => 2,
114            DynamicSize::Size4 => 4
115        }
116    }
117}
118
119impl Default for DynamicSize {
120    fn default() -> Self {
121        DynamicSize::Unset
122    }
123}
124
125#[derive(Default, Copy, Clone)]
126pub(crate) struct Column {
127    pub offset: u8,
128    pub size: u8,
129}
130
131pub(crate) trait ColumnAccess<Col> {
132    type ColumnSize: ColumnSize;
133}
134
135impl<T: TableDesc, Col: ColumnIndex> ColumnAccess<Col> for T
136    where <T as TableDesc>::Columns: ColumnTupleAccess<Col>
137{
138    type ColumnSize = <<T as TableDesc>::Columns as ColumnTupleAccess<Col>>::Out;
139}
140
141pub(crate) trait ReadValue<S: ColumnSize> {
142    fn read_value(input: &[u8], size: u8) -> Self;
143}
144
145impl ReadValue<FixedSize2> for u16 {
146    fn read_value(input: &[u8], _: u8) -> Self {
147        LittleEndian::read_u16(input)
148    }
149}
150
151impl ReadValue<FixedSize4> for u32 {
152    fn read_value(input: &[u8], _: u8) -> Self {
153        LittleEndian::read_u32(input)
154    }
155}
156
157impl ReadValue<FixedSize8> for u64 {
158    fn read_value(input: &[u8], _: u8) -> Self {
159        LittleEndian::read_u64(input)
160    }
161}
162
163impl ReadValue<DynamicSize> for u32 {
164    fn read_value(input: &[u8], size: u8) -> Self {
165        if size == 4 {
166            LittleEndian::read_u32(input)
167        } else {
168            LittleEndian::read_u16(input) as u32
169        }
170    }
171}