use serde::{Deserialize, Serialize};
use crate::identifier::QualifiedName;
use crate::ir::column_type::ColumnType;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Cast {
pub source: QualifiedName,
pub target: QualifiedName,
pub method: CastMethod,
pub context: CastContext,
pub comment: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum CastMethod {
Function {
name: QualifiedName,
arg_types: Vec<ColumnType>,
},
Inout,
Binary,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum CastContext {
Explicit,
Assignment,
Implicit,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::identifier::{Identifier, QualifiedName};
fn id(s: &str) -> Identifier {
Identifier::from_unquoted(s).unwrap()
}
fn qname(schema: &str, name: &str) -> QualifiedName {
QualifiedName::new(id(schema), id(name))
}
fn cast_function() -> Cast {
Cast {
source: qname("app", "my_type"),
target: qname("pg_catalog", "text"),
method: CastMethod::Function {
name: qname("app", "my_type_to_text"),
arg_types: vec![ColumnType::Integer],
},
context: CastContext::Explicit,
comment: Some("Converts my_type to text.".to_string()),
}
}
fn cast_inout() -> Cast {
Cast {
source: qname("app", "domain_a"),
target: qname("app", "domain_b"),
method: CastMethod::Inout,
context: CastContext::Assignment,
comment: None,
}
}
fn cast_binary() -> Cast {
Cast {
source: qname("app", "type_x"),
target: qname("app", "type_y"),
method: CastMethod::Binary,
context: CastContext::Implicit,
comment: None,
}
}
#[test]
fn cast_function_serde_round_trip() {
let c = cast_function();
let json = serde_json::to_string(&c).unwrap();
let back: Cast = serde_json::from_str(&json).unwrap();
assert_eq!(c, back);
}
#[test]
fn cast_inout_serde_round_trip() {
let c = cast_inout();
let json = serde_json::to_string(&c).unwrap();
let back: Cast = serde_json::from_str(&json).unwrap();
assert_eq!(c, back);
}
#[test]
fn cast_binary_serde_round_trip() {
let c = cast_binary();
let json = serde_json::to_string(&c).unwrap();
let back: Cast = serde_json::from_str(&json).unwrap();
assert_eq!(c, back);
}
#[test]
fn cast_context_serde_variants() {
let explicit = serde_json::to_string(&CastContext::Explicit).unwrap();
let assignment = serde_json::to_string(&CastContext::Assignment).unwrap();
let implicit = serde_json::to_string(&CastContext::Implicit).unwrap();
assert_eq!(explicit, "\"explicit\"");
assert_eq!(assignment, "\"assignment\"");
assert_eq!(implicit, "\"implicit\"");
let back_e: CastContext = serde_json::from_str(&explicit).unwrap();
let back_a: CastContext = serde_json::from_str(&assignment).unwrap();
let back_i: CastContext = serde_json::from_str(&implicit).unwrap();
assert_eq!(back_e, CastContext::Explicit);
assert_eq!(back_a, CastContext::Assignment);
assert_eq!(back_i, CastContext::Implicit);
}
}