use crate::tree::ast::identifier::{CompoundIdentifier, Identifier, SimpleIdentifier};
#[derive(Debug)]
pub struct IdentifierBuilder {
parts: Vec<SimpleIdentifier>,
}
impl IdentifierBuilder {
pub fn new(name: impl Into<String>) -> Self {
Self {
parts: vec![SimpleIdentifier::new(name)],
}
}
pub fn dot(mut self, name: impl Into<String>) -> Self {
self.parts.push(SimpleIdentifier::new(name));
self
}
pub fn build(&self) -> Identifier {
match self.parts.as_slice() {
[] => unreachable!("IdentifierBuilder always has at least one part"),
[single] => single.clone().into(),
[first, second, rest @ ..] => {
CompoundIdentifier::new(first.clone(), second.clone(), rest.to_vec()).into()
}
}
}
}
impl From<IdentifierBuilder> for Identifier {
fn from(builder: IdentifierBuilder) -> Self {
builder.build()
}
}
pub fn ident(name: impl Into<String>) -> IdentifierBuilder {
IdentifierBuilder::new(name)
}
impl From<String> for Identifier {
fn from(name: String) -> Self {
SimpleIdentifier::new(name).into()
}
}
impl From<&str> for Identifier {
fn from(name: &str) -> Self {
SimpleIdentifier::new(name).into()
}
}
#[cfg(test)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn test_simple_identifier() {
let id = ident("column").build();
match id {
Identifier::Simple(s) => assert!(s == "column"),
_ => panic!("Expected simple identifier"),
}
}
#[test]
fn test_compound_identifier_two_parts() {
let id = ident("table").dot("column").build();
match id {
Identifier::Compound(c) => {
assert_eq!(c.parts().len(), 2);
assert!(c.parts()[0] == "table");
assert!(c.parts()[1] == "column");
}
_ => panic!("Expected compound identifier"),
}
}
#[test]
fn test_compound_identifier_three_parts() {
let id = ident("schema").dot("table").dot("column").build();
match id {
Identifier::Compound(c) => {
assert_eq!(c.parts().len(), 3);
assert!(c.parts()[0] == "schema");
assert!(c.parts()[1] == "table");
assert!(c.parts()[2] == "column");
}
_ => panic!("Expected compound identifier"),
}
}
#[test]
fn test_identifier_from_string() {
let id: Identifier = "column".into();
match id {
Identifier::Simple(s) => assert!(s == "column"),
_ => panic!("Expected simple identifier"),
}
}
}