1use crate::functions::Value;
3use std::collections::HashMap;
4
5#[derive(Debug, Clone)]
7pub struct Row {
8 columns: HashMap<String, Value>,
9}
10
11impl Row {
12 pub fn new() -> Self {
14 Row {
15 columns: HashMap::new(),
16 }
17 }
18
19 pub fn from_values(names: &[String], values: Vec<Value>) -> Self {
21 let mut row = Row::new();
22 for (name, value) in names.iter().zip(values.iter()) {
23 row.set(name, value.clone());
24 }
25 row
26 }
27
28 pub fn get(&self, name: &str) -> Option<&Value> {
30 self.columns.get(name)
31 }
32
33 pub fn set(&mut self, name: &str, value: Value) {
35 self.columns.insert(name.to_string(), value);
36 }
37
38 pub fn column_names(&self) -> Vec<String> {
40 self.columns.keys().cloned().collect()
41 }
42
43 pub fn values(&self, columns: &[String]) -> Vec<Value> {
45 columns
46 .iter()
47 .map(|name| self.get(name).cloned().unwrap_or(Value::Null))
48 .collect()
49 }
50
51 pub fn as_map(&self) -> &HashMap<String, Value> {
53 &self.columns
54 }
55
56 pub fn len(&self) -> usize {
58 self.columns.len()
59 }
60
61 pub fn is_empty(&self) -> bool {
63 self.columns.is_empty()
64 }
65}
66
67impl Default for Row {
68 fn default() -> Self {
69 Self::new()
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 #[test]
78 fn test_row_creation() {
79 let mut row = Row::new();
80 row.set("name", Value::String("John".to_string()));
81 row.set("age", Value::Integer(30));
82
83 assert_eq!(row.get("name"), Some(&Value::String("John".to_string())));
84 assert_eq!(row.get("age"), Some(&Value::Integer(30)));
85 assert_eq!(row.get("missing"), None);
86 }
87
88 #[test]
89 fn test_row_from_values() {
90 let names = vec!["id".to_string(), "name".to_string()];
91 let values = vec![Value::Integer(1), Value::String("Alice".to_string())];
92 let row = Row::from_values(&names, values);
93
94 assert_eq!(row.get("id"), Some(&Value::Integer(1)));
95 assert_eq!(row.get("name"), Some(&Value::String("Alice".to_string())));
96 }
97}