sqlite_fsr/models/dbfile/dbtable/
tablerow.rs

1use std::fmt;
2use std::ops::{Index, IndexMut};
3use crate::models::dbfile::dbtable::tablepage::Record;
4
5#[derive(Debug)]
6pub struct TableRow {
7    pub row_id: i64,
8    pub column_values: Vec<String>
9}
10
11impl From<Record> for TableRow {
12    fn from(record: Record) -> Self {
13        let column_values: Vec<String> = record.column_values.iter()
14                                                             .map(|bytes| {
15                                                                 if bytes.is_empty() {
16                                                                     "NULL".to_string()
17                                                                 } else {
18                                                                     String::from_utf8_lossy(&bytes).to_string()
19                                                                 }
20                                                             })
21                                                             .collect();
22        let tablerow = TableRow { row_id: record.row_id, column_values };
23        return tablerow;
24    }
25}
26
27impl Index<usize> for TableRow {
28    type Output = String;
29    
30    fn index(&self, index: usize) -> &Self::Output {
31        &self.column_values[index]
32    }
33}
34
35impl IndexMut<usize> for TableRow {
36    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
37        &mut self.column_values[index]
38    }
39}
40
41impl fmt::Display for TableRow {
42    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
43        for i in 0..self.column_values.len() {
44            write!(f, "{}", self.column_values[i])?;
45            if i != self.column_values.len() - 1 { 
46                write!(f, " ")?; 
47            }
48        }
49        Ok(())
50    } 
51}
52
53// Wrapper so a vector of `TableRow` can be printed to the console.
54// You cannot implement `Display` directly for `Vec<TableRow>` due to Rust's
55// orphan rules, so we provide a small newtype wrapper instead.
56pub struct TableRows(pub Vec<TableRow>);
57
58impl From<Vec<TableRow>> for TableRows {
59    fn from(v: Vec<TableRow>) -> Self {
60        TableRows(v)
61    }
62}
63
64impl From<Vec<Record>> for TableRows {
65    fn from(records: Vec<Record>) -> Self {
66        let table_rows: Vec<TableRow> = records.into_iter()
67            .map(|record| TableRow::from(record))
68            .collect();
69        TableRows(table_rows)
70    }
71}
72
73impl fmt::Display for TableRows {
74    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
75        for rec in self.0.iter() {
76            writeln!(f, "{}", rec)?;
77        }
78        Ok(())
79    }
80}
81
82impl std::ops::Deref for TableRows {
83    type Target = [TableRow];
84    fn deref(&self) -> &Self::Target {
85        &self.0
86    }
87}
88
89impl std::ops::DerefMut for TableRows {
90    fn deref_mut(&mut self) -> &mut Self::Target {
91        &mut self.0
92    }
93}