use std::path::PathBuf;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Template {
pub elements: Vec<Element>,
pub source: TemplateSource,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum TemplateSource {
File(PathBuf),
Literal(String),
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Element {
Sql(String),
Bind(Binding),
Compose(ComposeRef),
Command(Command),
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Binding {
pub name: String,
pub min_values: Option<u32>,
pub max_values: Option<u32>,
pub nullable: bool,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum ComposeTarget {
Path(PathBuf),
Slot(String),
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct SlotAssignment {
pub name: String,
pub path: PathBuf,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ComposeRef {
pub target: ComposeTarget,
pub slots: Vec<SlotAssignment>,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Command {
pub kind: CommandKind,
pub distinct: bool,
pub all: bool,
pub columns: Option<Vec<String>>,
pub sources: Vec<PathBuf>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum CommandKind {
Count,
Union,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Dialect {
Postgres,
Mysql,
Sqlite,
}
impl Dialect {
pub fn placeholder(&self, index: usize) -> String {
match self {
Dialect::Postgres => format!("${index}"),
Dialect::Mysql => "?".to_string(),
Dialect::Sqlite => format!("?{index}"),
}
}
pub fn supports_numbered_placeholders(&self) -> bool {
matches!(self, Dialect::Postgres | Dialect::Sqlite)
}
}