try to use separate struct for primary language

feature/language-tags
Felix Ableitner 2021-04-21 22:43:17 +02:00
parent c1a686cf28
commit 12c632d2dd
5 changed files with 23 additions and 76 deletions

View File

@ -11,9 +11,10 @@ use diesel::{
serialize::{Output, ToSql}, serialize::{Output, ToSql},
sql_types::Text, sql_types::Text,
}; };
use language_tags::LanguageTag; use language_tags::{LanguageTag, ValidationError};
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Serialize};
use std::{ use std::{
convert::TryFrom,
fmt, fmt,
fmt::{Display, Formatter}, fmt::{Display, Formatter},
io::Write, io::Write,
@ -122,69 +123,15 @@ pub fn naive_now() -> NaiveDateTime {
} }
#[repr(transparent)] #[repr(transparent)]
#[derive(Clone, PartialEq, Debug, AsExpression, FromSqlRow)] #[derive(Clone, PartialEq, Serialize, Deserialize, Debug, AsExpression, Queryable)]
#[sql_type = "Text"] #[sql_type = "Text"]
pub struct DbLanguage(LanguageTag); pub struct PrimaryLanguageTag(String);
impl<DB: Backend> ToSql<Text, DB> for DbLanguage impl TryFrom<LanguageTag> for PrimaryLanguageTag {
where type Error = ValidationError;
String: ToSql<Text, DB>,
{
fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> diesel::serialize::Result {
self.0.to_string().to_sql(out)
}
}
// TODO: hopefully the crate will add serde support fn try_from(tag: LanguageTag) -> Result<Self, Self::Error> {
// https://github.com/pyfisch/rust-language-tags/issues/22 let canonical = tag.canonicalize()?;
impl Serialize for DbLanguage { Ok(PrimaryLanguageTag(canonical.primary_language().to_string()))
fn serialize<S>(&self, _serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer,
{
todo!()
}
}
impl<'de> Deserialize<'de> for DbLanguage {
fn deserialize<D>(_deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
where
D: Deserializer<'de>,
{
todo!()
}
}
impl<DB: Backend> FromSql<Text, DB> for DbLanguage
where
String: FromSql<Text, DB>,
{
fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result<Self> {
let str = String::from_sql(bytes)?;
Ok(DbLanguage(LanguageTag::parse(&str)?))
}
}
impl DbLanguage {
pub fn into_inner(self) -> LanguageTag {
self.0
}
}
impl Display for DbLanguage {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.to_owned().into_inner().fmt(f)
}
}
impl From<DbLanguage> for LanguageTag {
fn from(url: DbLanguage) -> Self {
url.0
}
}
impl From<LanguageTag> for DbLanguage {
fn from(lang: LanguageTag) -> Self {
DbLanguage(lang)
} }
} }

View File

@ -2,10 +2,10 @@ use crate::{
schema::{comment, comment_alias_1, comment_like, comment_saved}, schema::{comment, comment_alias_1, comment_like, comment_saved},
source::post::Post, source::post::Post,
CommentId, CommentId,
DbLanguage,
DbUrl, DbUrl,
PersonId, PersonId,
PostId, PostId,
PrimaryLanguageTag,
}; };
use serde::Serialize; use serde::Serialize;
@ -32,7 +32,7 @@ pub struct Comment {
pub deleted: bool, pub deleted: bool,
pub ap_id: DbUrl, pub ap_id: DbUrl,
pub local: bool, pub local: bool,
pub language: DbLanguage, pub language: PrimaryLanguageTag,
} }
#[derive(Clone, Queryable, Associations, Identifiable, PartialEq, Debug, Serialize)] #[derive(Clone, Queryable, Associations, Identifiable, PartialEq, Debug, Serialize)]
@ -67,7 +67,7 @@ pub struct CommentForm {
pub deleted: Option<bool>, pub deleted: Option<bool>,
pub ap_id: Option<DbUrl>, pub ap_id: Option<DbUrl>,
pub local: Option<bool>, pub local: Option<bool>,
pub language: Option<DbLanguage>, pub language: Option<PrimaryLanguageTag>,
} }
#[derive(Identifiable, Queryable, Associations, PartialEq, Debug, Clone)] #[derive(Identifiable, Queryable, Associations, PartialEq, Debug, Clone)]

View File

@ -1,4 +1,4 @@
use crate::{schema::local_user, DbLanguage, LocalUserId, PersonId}; use crate::{schema::local_user, LocalUserId, PersonId, PrimaryLanguageTag};
use serde::Serialize; use serde::Serialize;
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)] #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
@ -17,7 +17,7 @@ pub struct LocalUser {
pub send_notifications_to_email: bool, pub send_notifications_to_email: bool,
pub validator_time: chrono::NaiveDateTime, pub validator_time: chrono::NaiveDateTime,
pub show_scores: bool, pub show_scores: bool,
pub discussion_languages: Vec<DbLanguage>, pub discussion_languages: Vec<PrimaryLanguageTag>,
} }
// TODO redo these, check table defaults // TODO redo these, check table defaults
@ -35,7 +35,7 @@ pub struct LocalUserForm {
pub show_avatars: Option<bool>, pub show_avatars: Option<bool>,
pub send_notifications_to_email: Option<bool>, pub send_notifications_to_email: Option<bool>,
pub show_scores: Option<bool>, pub show_scores: Option<bool>,
pub discussion_languages: Option<Vec<DbLanguage>>, pub discussion_languages: Option<Vec<PrimaryLanguageTag>>,
} }
/// A local user view that removes password encrypted /// A local user view that removes password encrypted

View File

@ -1,10 +1,10 @@
use crate::{ use crate::{
schema::{post, post_like, post_read, post_saved}, schema::{post, post_like, post_read, post_saved},
CommunityId, CommunityId,
DbLanguage,
DbUrl, DbUrl,
PersonId, PersonId,
PostId, PostId,
PrimaryLanguageTag,
}; };
use serde::Serialize; use serde::Serialize;
@ -30,7 +30,7 @@ pub struct Post {
pub thumbnail_url: Option<DbUrl>, pub thumbnail_url: Option<DbUrl>,
pub ap_id: DbUrl, pub ap_id: DbUrl,
pub local: bool, pub local: bool,
pub language: DbLanguage, pub language: PrimaryLanguageTag,
} }
#[derive(Insertable, AsChangeset, Default)] #[derive(Insertable, AsChangeset, Default)]
@ -54,7 +54,7 @@ pub struct PostForm {
pub thumbnail_url: Option<DbUrl>, pub thumbnail_url: Option<DbUrl>,
pub ap_id: Option<DbUrl>, pub ap_id: Option<DbUrl>,
pub local: Option<bool>, pub local: Option<bool>,
pub language: Option<DbLanguage>, pub language: Option<PrimaryLanguageTag>,
} }
#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)] #[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]

View File

@ -1,4 +1,4 @@
use crate::{schema::private_message, DbLanguage, DbUrl, PersonId, PrivateMessageId}; use crate::{schema::private_message, DbUrl, PersonId, PrimaryLanguageTag, PrivateMessageId};
use serde::Serialize; use serde::Serialize;
#[derive(Clone, Queryable, Associations, Identifiable, PartialEq, Debug, Serialize)] #[derive(Clone, Queryable, Associations, Identifiable, PartialEq, Debug, Serialize)]
@ -14,7 +14,7 @@ pub struct PrivateMessage {
pub updated: Option<chrono::NaiveDateTime>, pub updated: Option<chrono::NaiveDateTime>,
pub ap_id: DbUrl, pub ap_id: DbUrl,
pub local: bool, pub local: bool,
pub language: DbLanguage, pub language: PrimaryLanguageTag,
} }
#[derive(Insertable, AsChangeset, Default)] #[derive(Insertable, AsChangeset, Default)]
@ -29,5 +29,5 @@ pub struct PrivateMessageForm {
pub updated: Option<chrono::NaiveDateTime>, pub updated: Option<chrono::NaiveDateTime>,
pub ap_id: Option<DbUrl>, pub ap_id: Option<DbUrl>,
pub local: Option<bool>, pub local: Option<bool>,
pub language: Option<DbLanguage>, pub language: Option<PrimaryLanguageTag>,
} }