chat: add Id<T> type
This commit is contained in:
parent
e57bff00c2
commit
ce543e7ee1
8 changed files with 146 additions and 43 deletions
103
foxchat/src/id.rs
Normal file
103
foxchat/src/id.rs
Normal file
|
@ -0,0 +1,103 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{
|
||||
database::{HasArguments, HasValueRef},
|
||||
encode::IsNull,
|
||||
error::BoxDynError,
|
||||
postgres::PgTypeInfo,
|
||||
Decode, Encode, Postgres, Type,
|
||||
};
|
||||
|
||||
pub struct Id<T>(pub String, PhantomData<T>)
|
||||
where
|
||||
T: IdType;
|
||||
|
||||
impl<T: IdType> Id<T> {
|
||||
pub fn new(value: String) -> Self {
|
||||
Self(value, PhantomData)
|
||||
}
|
||||
|
||||
pub fn from_str(value: &str) -> Self {
|
||||
value.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IdType> From<&str> for Id<T> {
|
||||
fn from(value: &str) -> Self {
|
||||
Self::new(value.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IdType> From<String> for Id<T> {
|
||||
fn from(value: String) -> Self {
|
||||
Self::new(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IdType> From<Id<T>> for String {
|
||||
fn from(value: Id<T>) -> Self {
|
||||
value.0
|
||||
}
|
||||
}
|
||||
|
||||
pub trait IdType: private::Sealed {}
|
||||
|
||||
pub struct GuildType;
|
||||
pub struct ChannelType;
|
||||
pub struct MessageType;
|
||||
pub struct UserType;
|
||||
|
||||
impl IdType for GuildType {}
|
||||
impl IdType for ChannelType {}
|
||||
impl IdType for MessageType {}
|
||||
impl IdType for UserType {}
|
||||
|
||||
mod private {
|
||||
use super::*;
|
||||
|
||||
pub trait Sealed {}
|
||||
|
||||
impl Sealed for GuildType {}
|
||||
impl Sealed for ChannelType {}
|
||||
impl Sealed for MessageType {}
|
||||
impl Sealed for UserType {}
|
||||
}
|
||||
|
||||
impl<T: IdType> Type<Postgres> for Id<T> {
|
||||
fn type_info() -> PgTypeInfo {
|
||||
<&str as Type<Postgres>>::type_info()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, T: IdType> Decode<'r, Postgres> for Id<T> {
|
||||
fn decode(value: <Postgres as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
|
||||
let value = <&str as Decode<Postgres>>::decode(value)?;
|
||||
|
||||
Ok(Id::<T>::new(value.parse()?))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q, T: IdType> Encode<'q, Postgres> for Id<T> {
|
||||
fn encode_by_ref(&self, buf: &mut <Postgres as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
|
||||
<&str as Encode<Postgres>>::encode(&self.0, buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IdType> Serialize for Id<T> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, T: IdType> Deserialize<'de> for Id<T> {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
Ok(Self::new(String::deserialize(deserializer)?))
|
||||
}
|
||||
}
|
|
@ -3,9 +3,11 @@ pub mod fed;
|
|||
pub mod http;
|
||||
pub mod model;
|
||||
pub mod s2s;
|
||||
pub mod id;
|
||||
|
||||
pub use error::FoxError;
|
||||
pub use fed::signature;
|
||||
pub use id::Id;
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use ulid::Ulid;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue