use core::fmt;
use std::fmt::{Debug, Display};
use serde::{de::Visitor, Deserialize, Serialize, Serializer};
use crate::{PrimaryKey, TableBuilder};
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct ForeignKey<T, D>
where
T: Display + 'static,
D: TableBuilder,
{
pub key: T,
pub data: D,
}
pub type ForeignKeyInteger<T> = ForeignKey<i32, T>;
pub type ForeignKeyString<T> = ForeignKey<String, T>;
#[cfg(feature = "uuid")]
pub type ForeignKeyUuid<T> = ForeignKey<uuid::Uuid, T>;
impl<T, D> Debug for ForeignKey<T, D>
where
T: Debug + Display + 'static,
D: TableBuilder,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "ForeignKey({})", self.key)
}
}
impl<T, D> Display for ForeignKey<T, D>
where
T: Display + 'static,
D: TableBuilder,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}({})", self.data.get_table().name, self.key)
}
}
impl<D> Default for ForeignKey<i32, D>
where
D: TableBuilder + Default,
{
fn default() -> Self {
Self {
key: Default::default(),
data: Default::default(),
}
}
}
impl<D> Default for ForeignKey<String, D>
where
D: TableBuilder + Default,
{
fn default() -> Self {
Self {
key: Default::default(),
data: Default::default(),
}
}
}
impl<D> ForeignKey<i32, D>
where
D: TableBuilder + Default,
{
pub fn new(value: i32) -> Self {
Self {
key: value,
data: Default::default(),
}
}
}
impl<D> ForeignKey<String, D>
where
D: TableBuilder + Default,
{
pub fn new(value: String) -> Self {
Self {
key: value,
data: Default::default(),
}
}
}
impl<D> From<i32> for ForeignKey<i32, D>
where
D: TableBuilder + Default,
{
fn from(value: i32) -> Self {
Self::new(value)
}
}
impl<D> From<String> for ForeignKey<String, D>
where
D: TableBuilder + Default,
{
fn from(value: String) -> Self {
Self::new(value)
}
}
impl<D> From<&str> for ForeignKey<String, D>
where
D: TableBuilder + Default,
{
fn from(value: &str) -> Self {
Self::new(value.to_string())
}
}
impl<D> From<ForeignKey<i32, D>> for i32
where
D: TableBuilder,
{
fn from(value: ForeignKey<i32, D>) -> Self {
value.key
}
}
impl<D> From<PrimaryKey<i32>> for ForeignKey<i32, D>
where
D: TableBuilder + Default,
{
fn from(value: PrimaryKey<i32>) -> Self {
Self::new(value.value)
}
}
impl<D> From<PrimaryKey<String>> for ForeignKey<String, D>
where
D: TableBuilder + Default,
{
fn from(value: PrimaryKey<String>) -> Self {
Self::new(value.value)
}
}
impl<D> Serialize for ForeignKeyInteger<D>
where
D: TableBuilder + Default,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_i32(self.key)
}
}
impl<'de, T> Deserialize<'de> for ForeignKeyInteger<T>
where
T: TableBuilder + Default + Serialize + Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<ForeignKeyInteger<T>, D::Error>
where
D: serde::Deserializer<'de>,
{
struct PrimaryKeyVisitor;
impl<'de> Visitor<'de> for PrimaryKeyVisitor {
type Value = i32;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an integer representing a foreign key")
}
fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(value)
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(v as i32)
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(v as i32)
}
}
Ok(ForeignKey::from(
deserializer.deserialize_i32(PrimaryKeyVisitor)?,
))
}
}