csvsql 0.1.4

SQL like engine that works on CSV file.
Documentation
use std::{ops::Deref, rc::Rc};

use sqlparser::ast::{Ident, ObjectName};
use thiserror::Error;

use crate::{
    result_set_metadata::Metadata,
    results_data::{DataRow, ResultsData},
    value::Value,
};

#[derive(Clone, Debug)]
pub struct Column {
    column: usize,
}
impl Column {
    pub fn get_index(&self) -> usize {
        self.column
    }
    pub fn from_index(column: usize) -> Self {
        Self { column }
    }
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
pub struct Name {
    elements: Vec<String>,
}

impl Name {
    pub fn append(&self, name: &str) -> Self {
        let mut elements = self.elements.clone();
        let name = name.to_string();
        elements.push(name);
        Self { elements }
    }
    pub fn parent(&self) -> Option<Self> {
        if self.elements.len() <= 1 {
            None
        } else {
            let mut elements = self.elements.clone();
            elements.pop();
            Some(Self { elements })
        }
    }
    pub fn full_name(&self) -> String {
        self.elements.join(".")
    }
    pub fn short_name(&self) -> &str {
        match self.elements.last() {
            None => "",
            Some(name) => name,
        }
    }
    pub fn available_names(&self) -> Vec<Self> {
        let short_name = self.short_name();
        let mut parent_list = match self.parent() {
            Some(parent) => parent
                .available_names()
                .iter()
                .map(|f| f.append(short_name))
                .collect(),
            None => vec![],
        };
        parent_list.push(short_name.into());
        parent_list
    }
}

impl From<&str> for Name {
    fn from(value: &str) -> Self {
        Self {
            elements: vec![value.to_string()],
        }
    }
}
impl From<String> for Name {
    fn from(value: String) -> Self {
        Self {
            elements: vec![value],
        }
    }
}
impl From<Vec<String>> for Name {
    fn from(value: Vec<String>) -> Self {
        Self { elements: value }
    }
}
impl From<&ObjectName> for Name {
    fn from(value: &ObjectName) -> Self {
        Self {
            elements: value.0.iter().map(|i| i.to_string()).collect(),
        }
    }
}
impl From<&Ident> for Name {
    fn from(value: &Ident) -> Self {
        Self {
            elements: vec![value.value.to_string()],
        }
    }
}

#[derive(Error, Debug)]
pub enum ColumnIndexError {
    #[error("Cannot find columns: `{0}`")]
    NoSuchColumn(String),
    #[error("Ambiguous column name: `{0}`")]
    AmbiguousColumnName(String),
}

pub struct ResultSet {
    pub metadata: Rc<Metadata>,
    pub data: ResultsData,
}
impl ResultSet {
    pub fn columns(&self) -> Box<dyn Iterator<Item = Column>> {
        self.metadata.columns()
    }
    pub fn value<'a>(&self, name: &Name, row: &'a DataRow) -> &'a Value {
        match self.metadata.column_index(name) {
            Ok(column) => row.get(column.deref()),
            Err(_) => &Value::Empty,
        }
    }
}