use core::any::Any;
use crate::{SQLParam, SQLSchemaType, SQLTable, TableRef, ToSQL};
pub trait DrizzlePolicy: Send + Sync + 'static {
const POLICY_NAME: &'static str;
const AS_CLAUSE: Option<&'static str> = None;
const FOR_CLAUSE: Option<&'static str> = None;
const TO: &'static [&'static str] = &[];
const USING: Option<&'static str> = None;
const WITH_CHECK: Option<&'static str> = None;
fn table_ref() -> &'static TableRef;
}
impl<T: DrizzlePolicy> SQLPolicyInfo for T {
fn table(&self) -> &'static TableRef {
T::table_ref()
}
fn name(&self) -> &'static str {
T::POLICY_NAME
}
fn as_clause(&self) -> Option<&'static str> {
T::AS_CLAUSE
}
fn for_clause(&self) -> Option<&'static str> {
T::FOR_CLAUSE
}
fn to(&self) -> &'static [&'static str] {
T::TO
}
fn using(&self) -> Option<&'static str> {
T::USING
}
fn with_check(&self) -> Option<&'static str> {
T::WITH_CHECK
}
}
pub trait SQLPolicyInfo: Any + Send + Sync {
fn table(&self) -> &'static TableRef;
fn name(&self) -> &'static str;
fn as_clause(&self) -> Option<&'static str>;
fn for_clause(&self) -> Option<&'static str>;
fn to(&self) -> &'static [&'static str];
fn using(&self) -> Option<&'static str>;
fn with_check(&self) -> Option<&'static str>;
}
impl core::fmt::Debug for dyn SQLPolicyInfo {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("SQLPolicyInfo")
.field("name", &self.name())
.field("table", &self.table().name)
.field("as_clause", &self.as_clause())
.field("for_clause", &self.for_clause())
.field("to", &self.to())
.finish()
}
}
#[diagnostic::on_unimplemented(
message = "`{Self}` is not a SQL policy for this dialect",
label = "ensure this type was derived with #[PostgresPolicy]"
)]
pub trait SQLPolicy<'a, Type: SQLSchemaType, Value: SQLParam + 'a>:
SQLPolicyInfo + ToSQL<'a, Value>
{
type Table: SQLTable<'a, Type, Value>;
}