use {
super::ExprNode,
crate::{
parse_sql::parse_assignment,
plan::AssignmentPlan,
result::{Error, Result},
translate::{NO_PARAMS, translate_assignment},
},
};
#[derive(Clone, Debug)]
pub enum AssignmentNode<'a> {
Expr(String, ExprNode<'a>),
Text(String),
}
impl From<&str> for AssignmentNode<'_> {
fn from(expr: &str) -> Self {
Self::Text(expr.to_owned())
}
}
impl<'a> TryFrom<AssignmentNode<'a>> for AssignmentPlan {
type Error = Error;
fn try_from(node: AssignmentNode<'a>) -> Result<Self> {
match node {
AssignmentNode::Text(expr) => {
let assignment = parse_assignment(expr)
.and_then(|assignment| translate_assignment(&assignment, NO_PARAMS))?;
Ok(assignment.into())
}
AssignmentNode::Expr(col, expr_node) => {
let value = expr_node.build_expr_plan()?;
let id = col;
Ok(AssignmentPlan { id, value })
}
}
}
}
#[cfg(test)]
mod tests {
use {
crate::{
parse_sql::parse_assignment,
plan::AssignmentPlan,
query_builder::AssignmentNode,
translate::{NO_PARAMS, translate_assignment},
},
pretty_assertions::assert_eq,
};
fn test(actual: AssignmentNode, expected: &str) {
let parsed = &parse_assignment(expected).expect(expected);
let expected = translate_assignment(parsed, NO_PARAMS).map(AssignmentPlan::from);
assert_eq!(actual.try_into(), expected);
}
#[test]
fn assignment() {
let actual = "foo = 1".into();
let expected = "foo = 1";
test(actual, expected);
let actual = r#"foo = "choco""#.into();
let expected = r#"foo = "choco""#;
test(actual, expected);
let actual = r"Bar = mild".into();
let expected = r"Bar = mild";
test(actual, expected);
let actual = AssignmentNode::Expr("foo".into(), "1".into());
let expected = "foo = 1";
test(actual, expected);
let actual = AssignmentNode::Expr("foo".into(), r#""cocoa""#.into());
let expected = r#"foo = "cocoa""#;
test(actual, expected);
let actual = AssignmentNode::Expr("Bar".into(), "mild".into());
let expected = "Bar = mild";
test(actual, expected);
}
}