use core::time::Duration;
use sea_orm::sea_query::{ArrayType, Nullable, ValueType, ValueTypeErr};
use sea_orm::{ColIdx, ColumnType, DbErr, QueryResult, TryFromU64, TryGetError, TryGetable, Value};
type SeaOrmRepr = i64;
type DurationRepr = u64;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
#[repr(transparent)]
pub struct Seconds(pub Duration);
impl From<Duration> for Seconds {
fn from(value: Duration) -> Self {
Self(Duration::from_secs(value.as_secs()))
}
}
impl From<Seconds> for Duration {
fn from(value: Seconds) -> Self {
value.0
}
}
impl ValueType for Seconds {
fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
<SeaOrmRepr as ValueType>::try_from(v)
.map(|i| DurationRepr::from_ne_bytes(i.to_ne_bytes()))
.map(Duration::from_secs)
.map(Self)
}
fn type_name() -> String {
core::any::type_name::<Self>().to_string()
}
fn array_type() -> ArrayType {
SeaOrmRepr::array_type()
}
fn column_type() -> ColumnType {
SeaOrmRepr::column_type()
}
}
impl From<Seconds> for Value {
fn from(value: Seconds) -> Self {
value.0.as_secs().into()
}
}
impl TryGetable for Seconds {
fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Self, TryGetError> {
SeaOrmRepr::try_get_by(res, index)
.map(|i| DurationRepr::from_ne_bytes(i.to_ne_bytes()))
.map(Duration::from_secs)
.map(Self)
}
}
impl TryFromU64 for Seconds {
fn try_from_u64(n: u64) -> Result<Self, DbErr> {
SeaOrmRepr::try_from_u64(n)
.map(|i| DurationRepr::from_ne_bytes(i.to_ne_bytes()))
.map(Duration::from_secs)
.map(Self)
}
}
impl Nullable for Seconds {
fn null() -> Value {
SeaOrmRepr::null()
}
}
#[cfg(test)]
mod tests {
use sea_orm::{
ActiveModelBehavior, DeriveEntityModel, DerivePrimaryKey, DeriveRelation, EntityTrait,
EnumIter, PrimaryKeyTrait,
};
use super::Seconds;
#[allow(dead_code)]
#[derive(Debug, Clone, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "seconds")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
id: u8,
#[sea_orm(primary_key, auto_increment = false)]
seconds: Seconds,
nullable: Option<Seconds>,
}
impl ActiveModelBehavior for ActiveModel {}
#[allow(dead_code)]
#[derive(Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
}