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},
sql_types::Text,
};
use language_tags::LanguageTag;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use language_tags::{LanguageTag, ValidationError};
use serde::{Deserialize, Serialize};
use std::{
convert::TryFrom,
fmt,
fmt::{Display, Formatter},
io::Write,
@ -122,69 +123,15 @@ pub fn naive_now() -> NaiveDateTime {
}
#[repr(transparent)]
#[derive(Clone, PartialEq, Debug, AsExpression, FromSqlRow)]
#[derive(Clone, PartialEq, Serialize, Deserialize, Debug, AsExpression, Queryable)]
#[sql_type = "Text"]
pub struct DbLanguage(LanguageTag);
pub struct PrimaryLanguageTag(String);
impl<DB: Backend> ToSql<Text, DB> for DbLanguage
where
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
// https://github.com/pyfisch/rust-language-tags/issues/22
impl Serialize for DbLanguage {
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)
impl TryFrom<LanguageTag> for PrimaryLanguageTag {
type Error = ValidationError;
fn try_from(tag: LanguageTag) -> Result<Self, Self::Error> {
let canonical = tag.canonicalize()?;
Ok(PrimaryLanguageTag(canonical.primary_language().to_string()))
}
}

View File

@ -2,10 +2,10 @@ use crate::{
schema::{comment, comment_alias_1, comment_like, comment_saved},
source::post::Post,
CommentId,
DbLanguage,
DbUrl,
PersonId,
PostId,
PrimaryLanguageTag,
};
use serde::Serialize;
@ -32,7 +32,7 @@ pub struct Comment {
pub deleted: bool,
pub ap_id: DbUrl,
pub local: bool,
pub language: DbLanguage,
pub language: PrimaryLanguageTag,
}
#[derive(Clone, Queryable, Associations, Identifiable, PartialEq, Debug, Serialize)]
@ -67,7 +67,7 @@ pub struct CommentForm {
pub deleted: Option<bool>,
pub ap_id: Option<DbUrl>,
pub local: Option<bool>,
pub language: Option<DbLanguage>,
pub language: Option<PrimaryLanguageTag>,
}
#[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;
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
@ -17,7 +17,7 @@ pub struct LocalUser {
pub send_notifications_to_email: bool,
pub validator_time: chrono::NaiveDateTime,
pub show_scores: bool,
pub discussion_languages: Vec<DbLanguage>,
pub discussion_languages: Vec<PrimaryLanguageTag>,
}
// TODO redo these, check table defaults
@ -35,7 +35,7 @@ pub struct LocalUserForm {
pub show_avatars: Option<bool>,
pub send_notifications_to_email: 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

View File

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