inline_postgres_impl/
key.rs
1use std::marker::PhantomData;
2
3use chrono::NaiveDateTime;
4use tokio_postgres as postgres;
5use tokio_postgres::types::{to_sql_checked, FromSql, ToSql};
6use ulid::Ulid;
7
8use crate::Table;
9
10use super::untyped_key;
11
12#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
20pub struct Key<T> {
21 key: untyped_key::Key,
22 _phantom: PhantomData<T>,
23}
24
25impl<T: Table> Clone for Key<T> {
26 fn clone(&self) -> Self {
27 *self
28 }
29}
30
31impl<T: Table> Copy for Key<T> {}
32
33impl<T: Table> FromSql<'_> for Key<T> {
34 fn from_sql(
35 ty: &postgres::types::Type,
36 raw: &[u8],
37 ) -> Result<Self, Box<dyn std::error::Error + Sync + Send>> {
38 Ok(Self {
39 key: untyped_key::Key::from_sql(ty, raw)?,
40 _phantom: PhantomData,
41 })
42 }
43
44 fn accepts(ty: &postgres::types::Type) -> bool {
45 untyped_key::Key::accepts_impl(ty)
46 }
47}
48impl<T: std::fmt::Debug + Table> ToSql for Key<T> {
49 fn to_sql(
50 &self,
51 ty: &postgres::types::Type,
52 out: &mut bytes::BytesMut,
53 ) -> Result<postgres::types::IsNull, Box<dyn std::error::Error + Sync + Send>>
54 where
55 Self: Sized,
56 {
57 self.key.to_sql(ty, out)
58 }
59
60 fn accepts(ty: &postgres::types::Type) -> bool
61 where
62 Self: Sized,
63 {
64 untyped_key::Key::accepts_impl(ty)
65 }
66
67 to_sql_checked!();
68}
69
70impl<T: Table> Key<T> {
71 pub fn from_untyped(key: untyped_key::Key) -> Self {
72 Self {
73 key,
74 _phantom: PhantomData,
75 }
76 }
77 pub fn new() -> Self {
78 Self {
79 key: untyped_key::Key::new(),
80 _phantom: PhantomData,
81 }
82 }
83 pub async fn fetch<C: postgres::GenericClient + Sync>(
84 self,
85 client: &C,
86 ) -> Result<Option<T>, postgres::Error> {
87 T::fetch_by_key(self, client).await
88 }
89 pub async fn delete<C: postgres::GenericClient + Sync>(
90 self,
91 client: &C,
92 ) -> Result<u64, postgres::Error> {
93 T::delete_by_key(self, client).await
94 }
95 pub fn inner(&self) -> Ulid {
96 self.key.0
97 }
98 pub fn timestamp(&self) -> NaiveDateTime {
99 let ms = self.key.0.timestamp_ms();
100 let ms = ms as i64;
101 NaiveDateTime::from_timestamp_millis(ms).unwrap()
102 }
103 pub fn untyped(&self) -> untyped_key::Key {
104 self.key
105 }
106}
107
108impl<T: Table + std::fmt::Debug> std::fmt::Debug for Key<T> {
109 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
110 write!(f, "{}", self.key.0)
111 }
112}