use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "candid", derive(candid::CandidType))]
pub enum JoinType {
Inner,
Left,
Right,
Full,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "candid", derive(candid::CandidType))]
pub struct Join {
pub join_type: JoinType,
pub table: String,
pub left_column: String,
pub right_column: String,
}
impl Join {
pub fn inner(table: &str, left_column: &str, right_column: &str) -> Self {
Self {
join_type: JoinType::Inner,
table: table.to_string(),
left_column: left_column.to_string(),
right_column: right_column.to_string(),
}
}
pub fn left(table: &str, left_column: &str, right_column: &str) -> Self {
Self {
join_type: JoinType::Left,
table: table.to_string(),
left_column: left_column.to_string(),
right_column: right_column.to_string(),
}
}
pub fn right(table: &str, left_column: &str, right_column: &str) -> Self {
Self {
join_type: JoinType::Right,
table: table.to_string(),
left_column: left_column.to_string(),
right_column: right_column.to_string(),
}
}
pub fn full(table: &str, left_column: &str, right_column: &str) -> Self {
Self {
join_type: JoinType::Full,
table: table.to_string(),
left_column: left_column.to_string(),
right_column: right_column.to_string(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_should_create_inner_join() {
let join = Join::inner("posts", "id", "user");
assert_eq!(join.join_type, JoinType::Inner);
assert_eq!(join.table, "posts");
assert_eq!(join.left_column, "id");
assert_eq!(join.right_column, "user");
}
#[test]
fn test_should_create_left_join() {
let join = Join::left("posts", "id", "user");
assert_eq!(join.join_type, JoinType::Left);
}
#[test]
fn test_should_create_right_join() {
let join = Join::right("posts", "id", "user");
assert_eq!(join.join_type, JoinType::Right);
}
#[test]
fn test_should_create_full_join() {
let join = Join::full("posts", "id", "user");
assert_eq!(join.join_type, JoinType::Full);
}
#[cfg(feature = "candid")]
#[test]
fn test_should_encode_decode_join_candid() {
let join = Join::inner("posts", "users.id", "user");
let encoded = candid::encode_one(&join).unwrap();
let decoded: Join = candid::decode_one(&encoded).unwrap();
assert_eq!(join, decoded);
}
#[cfg(feature = "candid")]
#[test]
fn test_should_encode_decode_join_type_candid() {
for jt in [
JoinType::Inner,
JoinType::Left,
JoinType::Right,
JoinType::Full,
] {
let encoded = candid::encode_one(&jt).unwrap();
let decoded: JoinType = candid::decode_one(&encoded).unwrap();
assert_eq!(jt, decoded);
}
}
}