diff --git a/Cargo.lock b/Cargo.lock index b5c654131..7986a471e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -122,7 +122,7 @@ dependencies = [ "httparse", "indexmap", "itoa", - "language-tags", + "language-tags 0.2.2", "lazy_static", "log", "mime", @@ -1568,7 +1568,7 @@ dependencies = [ "http", "httparse", "httpdate", - "language-tags", + "language-tags 0.2.2", "mime", "percent-encoding", "unicase", @@ -1719,6 +1719,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" +[[package]] +name = "language-tags" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3b2cac4f8e25c09c46826144a8b6e78520351824c247eff1a69a2aa6ebab26" + [[package]] name = "lazy_static" version = "1.4.0" @@ -1932,6 +1938,7 @@ dependencies = [ "chrono", "diesel", "diesel_migrations", + "language-tags 0.3.0", "lazy_static", "lemmy_db_schema", "lemmy_utils", @@ -1953,6 +1960,7 @@ dependencies = [ "chrono", "diesel", "diesel-derive-newtype", + "language-tags 0.3.0", "log", "serde", "serde_json", @@ -1964,6 +1972,7 @@ name = "lemmy_db_views" version = "0.1.0" dependencies = [ "diesel", + "language-tags 0.3.0", "lemmy_db_queries", "lemmy_db_schema", "log", diff --git a/crates/api/src/local_user.rs b/crates/api/src/local_user.rs index 241e3405f..7ea512c5f 100644 --- a/crates/api/src/local_user.rs +++ b/crates/api/src/local_user.rs @@ -235,9 +235,10 @@ impl Perform for SaveUserSettings { theme: data.theme.to_owned(), default_sort_type, default_listing_type, - lang: data.lang.to_owned(), + interface_language: data.interface_language.to_owned(), show_avatars: data.show_avatars, send_notifications_to_email: data.send_notifications_to_email, + discussion_languages: data.discussion_languages.to_owned(), }; let local_user_res = blocking(context.pool(), move |conn| { diff --git a/crates/api_common/src/comment.rs b/crates/api_common/src/comment.rs index 1457f181a..e264b7dc4 100644 --- a/crates/api_common/src/comment.rs +++ b/crates/api_common/src/comment.rs @@ -9,6 +9,7 @@ pub struct CreateComment { pub post_id: PostId, pub form_id: Option, pub auth: String, + pub language: String, } #[derive(Deserialize)] @@ -17,6 +18,7 @@ pub struct EditComment { pub comment_id: CommentId, pub form_id: Option, pub auth: String, + pub language: String, } #[derive(Deserialize)] diff --git a/crates/api_common/src/person.rs b/crates/api_common/src/person.rs index fc061a35b..73d2ec17b 100644 --- a/crates/api_common/src/person.rs +++ b/crates/api_common/src/person.rs @@ -16,7 +16,7 @@ pub struct Login { pub username_or_email: String, pub password: String, } -use lemmy_db_schema::{CommunityId, PersonId, PersonMentionId, PrivateMessageId}; +use lemmy_db_schema::{CommunityId, DbLanguage, PersonId, PersonMentionId, PrivateMessageId}; #[derive(Deserialize)] pub struct Register { @@ -27,6 +27,7 @@ pub struct Register { pub show_nsfw: bool, pub captcha_uuid: Option, pub captcha_answer: Option, + pub discussion_languages: Vec, } #[derive(Deserialize)] @@ -51,7 +52,7 @@ pub struct SaveUserSettings { pub theme: Option, pub default_sort_type: Option, pub default_listing_type: Option, - pub lang: Option, + pub interface_language: Option, pub avatar: Option, pub banner: Option, pub display_name: Option, @@ -61,6 +62,7 @@ pub struct SaveUserSettings { pub show_avatars: Option, pub send_notifications_to_email: Option, pub auth: String, + pub discussion_languages: Option>, } #[derive(Deserialize)] diff --git a/crates/api_common/src/post.rs b/crates/api_common/src/post.rs index 727859bc4..923d65e31 100644 --- a/crates/api_common/src/post.rs +++ b/crates/api_common/src/post.rs @@ -19,6 +19,7 @@ pub struct CreatePost { pub nsfw: bool, pub community_id: CommunityId, pub auth: String, + pub language: String, } #[derive(Serialize, Clone)] @@ -73,6 +74,7 @@ pub struct EditPost { pub body: Option, pub nsfw: bool, pub auth: String, + pub language: String, } #[derive(Deserialize)] diff --git a/crates/api_crud/src/site/read.rs b/crates/api_crud/src/site/read.rs index d3bf0d2d1..9efa06a61 100644 --- a/crates/api_crud/src/site/read.rs +++ b/crates/api_crud/src/site/read.rs @@ -37,6 +37,7 @@ impl PerformCrud for GetSite { show_nsfw: true, captcha_uuid: None, captcha_answer: None, + discussion_languages: vec![], }; let login_response = register.perform(context, websocket_id).await?; info!("Admin {} created", setup.admin_username); diff --git a/crates/api_crud/src/user/create.rs b/crates/api_crud/src/user/create.rs index be9fdbed9..a85751fcf 100644 --- a/crates/api_crud/src/user/create.rs +++ b/crates/api_crud/src/user/create.rs @@ -126,10 +126,11 @@ impl PerformCrud for Register { theme: Some("browser".into()), default_sort_type: Some(SortType::Active as i16), default_listing_type: Some(ListingType::Subscribed as i16), - lang: Some("browser".into()), + interface_language: Some("browser".into()), show_avatars: Some(true), show_scores: Some(true), send_notifications_to_email: Some(false), + discussion_languages: Some(data.discussion_languages.to_owned()), }; let inserted_local_user = match blocking(context.pool(), move |conn| { diff --git a/crates/apub/src/extensions/mod.rs b/crates/apub/src/extensions/mod.rs index 19e37894d..b7b7e959a 100644 --- a/crates/apub/src/extensions/mod.rs +++ b/crates/apub/src/extensions/mod.rs @@ -1,5 +1,6 @@ pub mod context; pub(crate) mod group_extension; +pub(crate) mod note_extension; pub(crate) mod page_extension; pub(crate) mod person_extension; pub mod signatures; diff --git a/crates/apub/src/extensions/note_extension.rs b/crates/apub/src/extensions/note_extension.rs new file mode 100644 index 000000000..c77ba0b60 --- /dev/null +++ b/crates/apub/src/extensions/note_extension.rs @@ -0,0 +1,40 @@ +use activitystreams::unparsed::UnparsedMutExt; +use activitystreams_ext::UnparsedExtension; +use lemmy_db_schema::DbLanguage; +use lemmy_utils::LemmyError; +use serde::{Deserialize, Serialize}; + +/// Activitystreams extension to allow (de)serializing additional Post fields +/// `comemnts_enabled` (called 'locked' in Lemmy), +/// `sensitive` (called 'nsfw') and `stickied`. +#[derive(Clone, Debug, Default, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct NoteExtension { + pub language: Option, +} + +impl NoteExtension { + pub fn new(language: DbLanguage) -> Result { + Ok(NoteExtension { + language: Some(language), + }) + } +} + +impl UnparsedExtension for NoteExtension +where + U: UnparsedMutExt, +{ + type Error = serde_json::Error; + + fn try_from_unparsed(unparsed_mut: &mut U) -> Result { + Ok(NoteExtension { + language: unparsed_mut.remove("language")?, + }) + } + + fn try_into_unparsed(self, unparsed_mut: &mut U) -> Result<(), Self::Error> { + unparsed_mut.insert("language", self.language)?; + Ok(()) + } +} diff --git a/crates/apub/src/extensions/page_extension.rs b/crates/apub/src/extensions/page_extension.rs index 752fa2b4b..353c4d12f 100644 --- a/crates/apub/src/extensions/page_extension.rs +++ b/crates/apub/src/extensions/page_extension.rs @@ -1,5 +1,7 @@ use activitystreams::unparsed::UnparsedMutExt; use activitystreams_ext::UnparsedExtension; +use lemmy_db_schema::DbLanguage; +use lemmy_utils::LemmyError; use serde::{Deserialize, Serialize}; /// Activitystreams extension to allow (de)serializing additional Post fields @@ -11,6 +13,23 @@ pub struct PageExtension { pub comments_enabled: Option, pub sensitive: Option, pub stickied: Option, + pub language: Option, +} + +impl PageExtension { + pub fn new( + comments_enabled: bool, + sensitive: bool, + stickied: bool, + language: DbLanguage, + ) -> Result { + Ok(PageExtension { + comments_enabled: Some(comments_enabled), + sensitive: Some(sensitive), + stickied: Some(stickied), + language: Some(language), + }) + } } impl UnparsedExtension for PageExtension @@ -24,6 +43,7 @@ where comments_enabled: unparsed_mut.remove("commentsEnabled")?, sensitive: unparsed_mut.remove("sensitive")?, stickied: unparsed_mut.remove("stickied")?, + language: unparsed_mut.remove("language")?, }) } @@ -31,6 +51,7 @@ where unparsed_mut.insert("commentsEnabled", self.comments_enabled)?; unparsed_mut.insert("sensitive", self.sensitive)?; unparsed_mut.insert("stickied", self.stickied)?; + unparsed_mut.insert("language", self.language)?; Ok(()) } } diff --git a/crates/apub/src/lib.rs b/crates/apub/src/lib.rs index 89109318a..7aba5f743 100644 --- a/crates/apub/src/lib.rs +++ b/crates/apub/src/lib.rs @@ -10,6 +10,7 @@ pub mod objects; use crate::{ extensions::{ group_extension::GroupExtension, + note_extension::NoteExtension, page_extension::PageExtension, person_extension::PersonExtension, signatures::{PublicKey, PublicKeyExtension}, @@ -53,7 +54,7 @@ pub type GroupExt = type PersonExt = Ext2>, PersonExtension, PublicKeyExtension>; /// Activitystreams type for post pub type PageExt = Ext1, PageExtension>; -pub type NoteExt = ApObject; +pub type NoteExt = Ext1, NoteExtension>; pub static APUB_JSON_CONTENT_TYPE: &str = "application/activity+json"; diff --git a/crates/apub/src/objects/comment.rs b/crates/apub/src/objects/comment.rs index 1480e5e95..b4b664ae0 100644 --- a/crates/apub/src/objects/comment.rs +++ b/crates/apub/src/objects/comment.rs @@ -1,5 +1,5 @@ use crate::{ - extensions::context::lemmy_context, + extensions::{context::lemmy_context, note_extension::NoteExtension}, fetcher::objects::{get_or_fetch_and_insert_comment, get_or_fetch_and_insert_post}, objects::{ check_object_domain, @@ -20,6 +20,7 @@ use activitystreams::{ prelude::*, public, }; +use activitystreams_ext::Ext1; use anyhow::{anyhow, Context}; use lemmy_api_common::blocking; use lemmy_db_queries::{Crud, DbPool}; @@ -82,7 +83,8 @@ impl ToApub for Comment { comment.set_updated(convert_datetime(u)); } - Ok(comment) + let ext = NoteExtension::new(self.language.to_owned())?; + Ok(Ext1::new(comment, ext)) } fn to_tombstone(&self) -> Result { @@ -204,6 +206,7 @@ impl FromApubToForm for CommentForm { deleted: None, ap_id: Some(check_object_domain(note, expected_domain)?), local: Some(false), + language: note.ext_one.language.to_owned(), }) } } diff --git a/crates/apub/src/objects/post.rs b/crates/apub/src/objects/post.rs index 57cb76524..4b13d439c 100644 --- a/crates/apub/src/objects/post.rs +++ b/crates/apub/src/objects/post.rs @@ -88,11 +88,12 @@ impl ToApub for Post { page.set_updated(convert_datetime(u)); } - let ext = PageExtension { - comments_enabled: Some(!self.locked), - sensitive: Some(self.nsfw), - stickied: Some(self.stickied), - }; + let ext = PageExtension::new( + !self.locked, + self.nsfw, + self.stickied, + self.language.to_owned(), + )?; Ok(Ext1::new(page, ext)) } @@ -239,6 +240,7 @@ impl FromApubToForm for PostForm { thumbnail_url: pictrs_thumbnail.map(|u| u.into()), ap_id: Some(ap_id), local: Some(false), + language: ext.language.to_owned(), }) } } diff --git a/crates/apub/src/objects/private_message.rs b/crates/apub/src/objects/private_message.rs index 5502fc355..3f0b8e798 100644 --- a/crates/apub/src/objects/private_message.rs +++ b/crates/apub/src/objects/private_message.rs @@ -1,6 +1,6 @@ use crate::{ check_is_apub_id_valid, - extensions::context::lemmy_context, + extensions::{context::lemmy_context, note_extension::NoteExtension}, fetcher::person::get_or_fetch_and_upsert_person, objects::{ check_object_domain, @@ -18,6 +18,7 @@ use activitystreams::{ object::{kind::NoteType, ApObject, Note, Tombstone}, prelude::*, }; +use activitystreams_ext::Ext1; use anyhow::Context; use lemmy_api_common::blocking; use lemmy_db_queries::{Crud, DbPool}; @@ -55,7 +56,8 @@ impl ToApub for PrivateMessage { private_message.set_updated(convert_datetime(u)); } - Ok(private_message) + let ext = NoteExtension::new(self.language.to_owned())?; + Ok(Ext1::new(private_message, ext)) } fn to_tombstone(&self) -> Result { @@ -131,6 +133,7 @@ impl FromApubToForm for PrivateMessageForm { read: None, ap_id: Some(check_object_domain(note, expected_domain)?), local: Some(false), + language: note.ext_one.language.to_owned(), }) } } diff --git a/crates/db_queries/Cargo.toml b/crates/db_queries/Cargo.toml index c950eea95..715f3d8c9 100644 --- a/crates/db_queries/Cargo.toml +++ b/crates/db_queries/Cargo.toml @@ -24,6 +24,7 @@ url = { version = "2.2.1", features = ["serde"] } lazy_static = "1.4.0" regex = "1.4.3" bcrypt = "0.9.0" +language-tags = "0.3.0" [dev-dependencies] serial_test = "0.5.1" \ No newline at end of file diff --git a/crates/db_queries/src/source/comment.rs b/crates/db_queries/src/source/comment.rs index 1eec0c987..e41aa6ff5 100644 --- a/crates/db_queries/src/source/comment.rs +++ b/crates/db_queries/src/source/comment.rs @@ -290,6 +290,7 @@ mod tests { updated: None, ap_id: inserted_comment.ap_id.to_owned(), local: true, + language: None, }; let child_comment_form = CommentForm { diff --git a/crates/db_queries/src/source/local_user.rs b/crates/db_queries/src/source/local_user.rs index d1fad2e85..a1e07957c 100644 --- a/crates/db_queries/src/source/local_user.rs +++ b/crates/db_queries/src/source/local_user.rs @@ -20,7 +20,7 @@ mod safe_settings_type { theme, default_sort_type, default_listing_type, - lang, + interface_language, show_avatars, send_notifications_to_email, validator_time, @@ -40,7 +40,7 @@ mod safe_settings_type { theme, default_sort_type, default_listing_type, - lang, + interface_language, show_avatars, send_notifications_to_email, validator_time, diff --git a/crates/db_queries/src/source/post.rs b/crates/db_queries/src/source/post.rs index 0205dc954..8220ae3e3 100644 --- a/crates/db_queries/src/source/post.rs +++ b/crates/db_queries/src/source/post.rs @@ -315,6 +315,7 @@ mod tests { thumbnail_url: None, ap_id: inserted_post.ap_id.to_owned(), local: true, + language: None, }; // Post Like diff --git a/crates/db_schema/Cargo.toml b/crates/db_schema/Cargo.toml index 70f3364e5..d79dd0fa8 100644 --- a/crates/db_schema/Cargo.toml +++ b/crates/db_schema/Cargo.toml @@ -14,3 +14,4 @@ serde_json = { version = "1.0.61", features = ["preserve_order"] } log = "0.4.14" url = { version = "2.2.1", features = ["serde"] } diesel-derive-newtype = "0.1" +language-tags = "0.3.0" diff --git a/crates/db_schema/src/lib.rs b/crates/db_schema/src/lib.rs index 4efa983fe..2bbaea516 100644 --- a/crates/db_schema/src/lib.rs +++ b/crates/db_schema/src/lib.rs @@ -11,7 +11,8 @@ use diesel::{ serialize::{Output, ToSql}, sql_types::Text, }; -use serde::{Deserialize, Serialize}; +use language_tags::LanguageTag; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::{ fmt, fmt::{Display, Formatter}, @@ -119,3 +120,71 @@ impl From for DbUrl { pub fn naive_now() -> NaiveDateTime { chrono::prelude::Utc::now().naive_utc() } + +#[repr(transparent)] +#[derive(Clone, PartialEq, Debug, AsExpression, FromSqlRow)] +#[sql_type = "Text"] +pub struct DbLanguage(LanguageTag); + +impl ToSql for DbLanguage +where + String: ToSql, +{ + fn to_sql(&self, out: &mut Output) -> 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(&self, _serializer: S) -> Result<::Ok, ::Error> + where + S: Serializer, + { + todo!() + } +} + +impl<'de> Deserialize<'de> for DbLanguage { + fn deserialize(_deserializer: D) -> Result>::Error> + where + D: Deserializer<'de>, + { + todo!() + } +} + +impl FromSql for DbLanguage +where + String: FromSql, +{ + fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result { + 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 for LanguageTag { + fn from(url: DbLanguage) -> Self { + url.0 + } +} + +impl From for DbLanguage { + fn from(lang: LanguageTag) -> Self { + DbLanguage(lang) + } +} diff --git a/crates/db_schema/src/schema.rs b/crates/db_schema/src/schema.rs index 9b05d29ab..7c27a730b 100644 --- a/crates/db_schema/src/schema.rs +++ b/crates/db_schema/src/schema.rs @@ -24,6 +24,7 @@ table! { deleted -> Bool, ap_id -> Varchar, local -> Bool, + language -> Text, } } @@ -149,11 +150,12 @@ table! { theme -> Varchar, default_sort_type -> Int2, default_listing_type -> Int2, - lang -> Varchar, + interface_language -> Varchar, show_avatars -> Bool, send_notifications_to_email -> Bool, validator_time -> Timestamp, show_scores -> Bool, + discussion_languages -> Array, } } @@ -340,6 +342,7 @@ table! { thumbnail_url -> Nullable, ap_id -> Varchar, local -> Bool, + language -> Text, } } @@ -414,6 +417,7 @@ table! { updated -> Nullable, ap_id -> Varchar, local -> Bool, + language -> Text, } } diff --git a/crates/db_schema/src/source/comment.rs b/crates/db_schema/src/source/comment.rs index bd36a48e8..71e074a7b 100644 --- a/crates/db_schema/src/source/comment.rs +++ b/crates/db_schema/src/source/comment.rs @@ -2,6 +2,7 @@ use crate::{ schema::{comment, comment_alias_1, comment_like, comment_saved}, source::post::Post, CommentId, + DbLanguage, DbUrl, PersonId, PostId, @@ -31,6 +32,7 @@ pub struct Comment { pub deleted: bool, pub ap_id: DbUrl, pub local: bool, + pub language: DbLanguage, } #[derive(Clone, Queryable, Associations, Identifiable, PartialEq, Debug, Serialize)] @@ -65,6 +67,7 @@ pub struct CommentForm { pub deleted: Option, pub ap_id: Option, pub local: Option, + pub language: Option, } #[derive(Identifiable, Queryable, Associations, PartialEq, Debug, Clone)] diff --git a/crates/db_schema/src/source/local_user.rs b/crates/db_schema/src/source/local_user.rs index 0a7181fdb..47eac1df6 100644 --- a/crates/db_schema/src/source/local_user.rs +++ b/crates/db_schema/src/source/local_user.rs @@ -1,4 +1,4 @@ -use crate::{schema::local_user, LocalUserId, PersonId}; +use crate::{schema::local_user, DbLanguage, LocalUserId, PersonId}; use serde::Serialize; #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)] @@ -12,11 +12,12 @@ pub struct LocalUser { pub theme: String, pub default_sort_type: i16, pub default_listing_type: i16, - pub lang: String, + pub interface_language: String, pub show_avatars: bool, pub send_notifications_to_email: bool, pub validator_time: chrono::NaiveDateTime, pub show_scores: bool, + pub discussion_languages: Vec, } // TODO redo these, check table defaults @@ -30,10 +31,11 @@ pub struct LocalUserForm { pub theme: Option, pub default_sort_type: Option, pub default_listing_type: Option, - pub lang: Option, + pub interface_language: Option, pub show_avatars: Option, pub send_notifications_to_email: Option, pub show_scores: Option, + pub discussion_languages: Option>, } /// A local user view that removes password encrypted @@ -47,7 +49,7 @@ pub struct LocalUserSettings { pub theme: String, pub default_sort_type: i16, pub default_listing_type: i16, - pub lang: String, + pub interface_language: String, pub show_avatars: bool, pub send_notifications_to_email: bool, pub validator_time: chrono::NaiveDateTime, diff --git a/crates/db_schema/src/source/post.rs b/crates/db_schema/src/source/post.rs index 2581db95c..1d3f64552 100644 --- a/crates/db_schema/src/source/post.rs +++ b/crates/db_schema/src/source/post.rs @@ -1,6 +1,7 @@ use crate::{ schema::{post, post_like, post_read, post_saved}, CommunityId, + DbLanguage, DbUrl, PersonId, PostId, @@ -29,6 +30,7 @@ pub struct Post { pub thumbnail_url: Option, pub ap_id: DbUrl, pub local: bool, + pub language: DbLanguage, } #[derive(Insertable, AsChangeset, Default)] @@ -52,6 +54,7 @@ pub struct PostForm { pub thumbnail_url: Option, pub ap_id: Option, pub local: Option, + pub language: Option, } #[derive(Identifiable, Queryable, Associations, PartialEq, Debug)] diff --git a/crates/db_schema/src/source/private_message.rs b/crates/db_schema/src/source/private_message.rs index 6710c2dcf..9e52fdc38 100644 --- a/crates/db_schema/src/source/private_message.rs +++ b/crates/db_schema/src/source/private_message.rs @@ -1,4 +1,4 @@ -use crate::{schema::private_message, DbUrl, PersonId, PrivateMessageId}; +use crate::{schema::private_message, DbLanguage, DbUrl, PersonId, PrivateMessageId}; use serde::Serialize; #[derive(Clone, Queryable, Associations, Identifiable, PartialEq, Debug, Serialize)] @@ -14,6 +14,7 @@ pub struct PrivateMessage { pub updated: Option, pub ap_id: DbUrl, pub local: bool, + pub language: DbLanguage, } #[derive(Insertable, AsChangeset, Default)] @@ -28,4 +29,5 @@ pub struct PrivateMessageForm { pub updated: Option, pub ap_id: Option, pub local: Option, + pub language: Option, } diff --git a/crates/db_views/Cargo.toml b/crates/db_views/Cargo.toml index 42a942b40..5d132a463 100644 --- a/crates/db_views/Cargo.toml +++ b/crates/db_views/Cargo.toml @@ -13,6 +13,7 @@ diesel = { version = "1.4.5", features = ["postgres","chrono","r2d2","serde_json serde = { version = "1.0.123", features = ["derive"] } log = "0.4.14" url = "2.2.1" +language-tags = "0.3.0" [dev-dependencies] serial_test = "0.5.1" \ No newline at end of file diff --git a/crates/db_views/src/comment_view.rs b/crates/db_views/src/comment_view.rs index fd2debf2c..02fedab21 100644 --- a/crates/db_views/src/comment_view.rs +++ b/crates/db_views/src/comment_view.rs @@ -438,6 +438,7 @@ impl ViewToVec for CommentView { #[cfg(test)] mod tests { use crate::comment_view::*; + use language_tags::LanguageTag; use lemmy_db_queries::{ aggregates::comment_aggregates::CommentAggregates, establish_unpooled_connection, @@ -514,6 +515,7 @@ mod tests { ap_id: inserted_comment.ap_id, updated: None, local: true, + language: LanguageTag::parse("en").unwrap().into(), }, creator: PersonSafe { id: inserted_person.id, @@ -554,6 +556,7 @@ mod tests { thumbnail_url: None, ap_id: inserted_post.ap_id.to_owned(), local: true, + language: LanguageTag::parse("en").unwrap().into(), }, community: CommunitySafe { id: inserted_community.id, diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs index a6843416e..5297b813c 100644 --- a/crates/db_views/src/post_view.rs +++ b/crates/db_views/src/post_view.rs @@ -432,6 +432,7 @@ impl ViewToVec for PostView { #[cfg(test)] mod tests { use crate::post_view::{PostQueryBuilder, PostView}; + use language_tags::LanguageTag; use lemmy_db_queries::{ aggregates::post_aggregates::PostAggregates, establish_unpooled_connection, @@ -535,6 +536,7 @@ mod tests { thumbnail_url: None, ap_id: inserted_post.ap_id.to_owned(), local: true, + language: LanguageTag::parse("en").unwrap().into(), }, my_vote: None, creator: PersonSafe {