criware_utf_core/
schema.rs1use crate::{Error, Reader, Result, ValueKind};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum ColumnStorageFormat {
7 Zero,
9 Constant,
11 Rowed,
13}
14
15#[derive(Debug, Clone)]
18pub struct SchemaColumn {
19 pub name: String,
21 pub storage_format: ColumnStorageFormat,
23 pub value_kind: ValueKind,
25}
26
27#[derive(Debug, Clone)]
32pub struct Schema {
33 pub table_name: String,
35 pub columns: Box<[SchemaColumn]>,
37}
38
39impl Reader {
40 fn get_column(&mut self) -> Result<SchemaColumn> {
41 let flag: u8 = self.read_value(false)?;
42 let column_name: String = self.read_value(false)?;
43 let value_kind = match flag & 0x0f {
44 0 => ValueKind::U8,
45 1 => ValueKind::I8,
46 2 => ValueKind::U16,
47 3 => ValueKind::I16,
48 4 => ValueKind::U32,
49 5 => ValueKind::I32,
50 6 => ValueKind::U64,
51 7 => ValueKind::I64,
52 8 => ValueKind::F32,
53 0xa => ValueKind::STR,
54 0xb => ValueKind::BLOB,
55 v => return Err(Error::InvalidColumnType(v)),
56 };
57 match flag & 0xf0 {
58 0x10 => Ok(SchemaColumn {
59 name: column_name,
60 storage_format: ColumnStorageFormat::Zero,
61 value_kind,
62 }),
63 0x30 => {
64 match value_kind {
65 ValueKind::U8 | ValueKind::I8 => {
66 self.read_value::<u8>(false)?;
67 }
68 ValueKind::U16 | ValueKind::I16 => {
69 self.read_value::<u16>(false)?;
70 }
71 ValueKind::U32 | ValueKind::I32 | ValueKind::F32 | ValueKind::STR => {
72 self.read_value::<u32>(false)?;
73 }
74 ValueKind::U64 | ValueKind::I64 | ValueKind::BLOB => {
75 self.read_value::<u64>(false)?;
76 }
77 };
78 Ok(SchemaColumn {
79 name: column_name,
80 storage_format: ColumnStorageFormat::Constant,
81 value_kind,
82 })
83 }
84 0x50 => Ok(SchemaColumn {
85 name: column_name,
86 storage_format: ColumnStorageFormat::Rowed,
87 value_kind,
88 }),
89 v => Err(Error::InvalidColumnStorage(v)),
90 }
91 }
92}
93
94impl Schema {
95 pub fn has_column(&self, name: &str) -> bool {
112 for column in &self.columns {
113 if column.name == name {
114 return true;
115 }
116 }
117 false
118 }
119 pub fn read(reader: &mut dyn std::io::Read) -> Result<Self> {
134 let mut reader = Reader::new(reader)?;
135 let mut columns = Vec::new();
136 while reader.more_column_data() {
137 columns.push(reader.get_column()?);
138 }
139 Ok(Schema {
140 table_name: reader.table_name().to_owned(),
141 columns: columns.into_boxed_slice(),
142 })
143 }
144}