add newtype
This commit is contained in:
parent
76e5e31411
commit
1455068e0c
10 changed files with 101 additions and 52 deletions
|
@ -9,6 +9,7 @@ edition = "2021"
|
||||||
async-trait = "0.1.68"
|
async-trait = "0.1.68"
|
||||||
chrono = "0.4.24"
|
chrono = "0.4.24"
|
||||||
database = { path = "../database" }
|
database = { path = "../database" }
|
||||||
|
derive_more = "0.99.17"
|
||||||
jsonschema = "0.17.0"
|
jsonschema = "0.17.0"
|
||||||
once_cell = "1.17.1"
|
once_cell = "1.17.1"
|
||||||
parse-display = "0.8.0"
|
parse-display = "0.8.0"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
|
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
|
||||||
|
|
||||||
use super::sea_orm_active_enums::AntennaSrcEnum;
|
use super::{newtype, sea_orm_active_enums::AntennaSrcEnum};
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
|
||||||
|
@ -17,7 +17,7 @@ pub struct Model {
|
||||||
#[sea_orm(column_name = "userListId")]
|
#[sea_orm(column_name = "userListId")]
|
||||||
pub user_list_id: Option<String>,
|
pub user_list_id: Option<String>,
|
||||||
#[sea_orm(column_type = "JsonBinary")]
|
#[sea_orm(column_type = "JsonBinary")]
|
||||||
pub keywords: Json,
|
pub keywords: newtype::Keyword,
|
||||||
#[sea_orm(column_name = "withFile")]
|
#[sea_orm(column_name = "withFile")]
|
||||||
pub with_file: bool,
|
pub with_file: bool,
|
||||||
pub expression: Option<String>,
|
pub expression: Option<String>,
|
||||||
|
@ -28,11 +28,11 @@ pub struct Model {
|
||||||
pub with_replies: bool,
|
pub with_replies: bool,
|
||||||
#[sea_orm(column_name = "userGroupJoiningId")]
|
#[sea_orm(column_name = "userGroupJoiningId")]
|
||||||
pub user_group_joining_id: Option<String>,
|
pub user_group_joining_id: Option<String>,
|
||||||
pub users: Vec<String>,
|
pub users: newtype::StringVec,
|
||||||
#[sea_orm(column_name = "excludeKeywords", column_type = "JsonBinary")]
|
#[sea_orm(column_name = "excludeKeywords", column_type = "JsonBinary")]
|
||||||
pub exclude_keywords: Json,
|
pub exclude_keywords: newtype::Keyword,
|
||||||
#[sea_orm(column_type = "JsonBinary")]
|
#[sea_orm(column_type = "JsonBinary")]
|
||||||
pub instances: Json,
|
pub instances: newtype::StringVec,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
|
|
@ -33,6 +33,7 @@ pub mod migrations;
|
||||||
pub mod moderation_log;
|
pub mod moderation_log;
|
||||||
pub mod muted_note;
|
pub mod muted_note;
|
||||||
pub mod muting;
|
pub mod muting;
|
||||||
|
pub mod newtype;
|
||||||
pub mod note;
|
pub mod note;
|
||||||
pub mod note_edit;
|
pub mod note_edit;
|
||||||
pub mod note_favorite;
|
pub mod note_favorite;
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! impl_json_newtype {
|
||||||
|
($a:tt) => {
|
||||||
|
impl From<$a> for Value {
|
||||||
|
fn from(source: $a) -> Self {
|
||||||
|
Value::Json(serde_json::to_value(source).ok().map(Box::new))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryGetable for $a {
|
||||||
|
fn try_get_by<I: sea_orm::ColIdx>(
|
||||||
|
res: &QueryResult,
|
||||||
|
idx: I,
|
||||||
|
) -> Result<Self, TryGetError> {
|
||||||
|
let json_value: serde_json::Value =
|
||||||
|
res.try_get_by(idx).map_err(TryGetError::DbErr)?;
|
||||||
|
serde_json::from_value(json_value)
|
||||||
|
.map_err(|e| TryGetError::DbErr(DbErr::Json(e.to_string())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sea_query::ValueType for $a {
|
||||||
|
fn try_from(v: Value) -> Result<Self, sea_query::ValueTypeErr> {
|
||||||
|
match v {
|
||||||
|
Value::Json(Some(x)) => Ok($a(
|
||||||
|
serde_json::from_value(*x).map_err(|_| sea_query::ValueTypeErr)?
|
||||||
|
)),
|
||||||
|
_ => Err(sea_query::ValueTypeErr),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_name() -> String {
|
||||||
|
stringify!($a).to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn array_type() -> sea_orm::sea_query::ArrayType {
|
||||||
|
sea_orm::sea_query::ArrayType::Json
|
||||||
|
}
|
||||||
|
|
||||||
|
fn column_type() -> sea_query::ColumnType {
|
||||||
|
sea_query::ColumnType::Json
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sea_query::Nullable for $a {
|
||||||
|
fn null() -> Value {
|
||||||
|
Value::Json(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
mod macros;
|
||||||
|
|
||||||
|
use derive_more::From;
|
||||||
|
use schemars::JsonSchema;
|
||||||
|
use sea_orm::{sea_query, DbErr, QueryResult, TryGetError, TryGetable, Value};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::impl_json_newtype;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, From)]
|
||||||
|
pub struct Keyword(pub Vec<Vec<String>>);
|
||||||
|
impl_json_newtype!(Keyword);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, From)]
|
||||||
|
|
||||||
|
pub struct StringVec(pub Vec<String>);
|
||||||
|
impl_json_newtype!(StringVec);
|
|
@ -3,7 +3,7 @@ use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
|
||||||
|
|
||||||
use crate::entity::{antenna, antenna_note, user_group_joining};
|
use crate::entity::{antenna, antenna_note, user_group_joining};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::schema::{antenna::Antenna, json_to_keyword, json_to_string_list};
|
use crate::schema::antenna::Antenna;
|
||||||
|
|
||||||
use super::Repository;
|
use super::Repository;
|
||||||
|
|
||||||
|
@ -30,13 +30,13 @@ impl Repository<Antenna> for antenna::Model {
|
||||||
id: self.id,
|
id: self.id,
|
||||||
created_at: self.created_at.into(),
|
created_at: self.created_at.into(),
|
||||||
name: self.name,
|
name: self.name,
|
||||||
keywords: json_to_keyword(&self.keywords),
|
keywords: self.keywords,
|
||||||
exclude_keywords: json_to_keyword(&self.exclude_keywords),
|
exclude_keywords: self.exclude_keywords,
|
||||||
src: self.src.try_into()?,
|
src: self.src.try_into()?,
|
||||||
user_list_id: self.user_list_id,
|
user_list_id: self.user_list_id,
|
||||||
user_group_id,
|
user_group_id,
|
||||||
users: self.users,
|
users: self.users,
|
||||||
instances: json_to_string_list(&self.instances),
|
instances: self.instances,
|
||||||
case_sensitive: self.case_sensitive,
|
case_sensitive: self.case_sensitive,
|
||||||
notify: self.notify,
|
notify: self.notify,
|
||||||
with_replies: self.with_replies,
|
with_replies: self.with_replies,
|
||||||
|
|
|
@ -4,8 +4,8 @@ use parse_display::FromStr;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use utoipa::ToSchema;
|
use utoipa::ToSchema;
|
||||||
|
|
||||||
use super::{Keyword, Schema, StringList};
|
use super::Schema;
|
||||||
use crate::entity::sea_orm_active_enums::AntennaSrcEnum;
|
use crate::entity::{newtype, sea_orm_active_enums::AntennaSrcEnum};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, JsonSchema, ToSchema)]
|
#[derive(Clone, Debug, PartialEq, Eq, JsonSchema, ToSchema)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
|
@ -13,14 +13,14 @@ pub struct Antenna {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub created_at: chrono::DateTime<chrono::Utc>,
|
pub created_at: chrono::DateTime<chrono::Utc>,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub keywords: Keyword,
|
pub keywords: newtype::Keyword,
|
||||||
pub exclude_keywords: Keyword,
|
pub exclude_keywords: newtype::Keyword,
|
||||||
#[schema(inline)]
|
#[schema(inline)]
|
||||||
pub src: AntennaSrc,
|
pub src: AntennaSrc,
|
||||||
pub user_list_id: Option<String>,
|
pub user_list_id: Option<String>,
|
||||||
pub user_group_id: Option<String>,
|
pub user_group_id: Option<String>,
|
||||||
pub users: StringList,
|
pub users: newtype::StringVec,
|
||||||
pub instances: StringList,
|
pub instances: newtype::StringVec,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub case_sensitive: bool,
|
pub case_sensitive: bool,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
|
|
@ -3,10 +3,6 @@ pub mod app;
|
||||||
|
|
||||||
use jsonschema::JSONSchema;
|
use jsonschema::JSONSchema;
|
||||||
use schemars::{schema_for, JsonSchema};
|
use schemars::{schema_for, JsonSchema};
|
||||||
use serde_json::Value;
|
|
||||||
|
|
||||||
type Keyword = Vec<Vec<String>>;
|
|
||||||
type StringList = Vec<String>;
|
|
||||||
|
|
||||||
/// Structs of schema defitions implement this trait in order to
|
/// Structs of schema defitions implement this trait in order to
|
||||||
/// provide the JSON Schema validator [`jsonschema::JSONSchema`].
|
/// provide the JSON Schema validator [`jsonschema::JSONSchema`].
|
||||||
|
@ -23,29 +19,3 @@ trait Schema<T: JsonSchema> {
|
||||||
.expect("Unable to compile schema")
|
.expect("Unable to compile schema")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn json_to_keyword(value: &Value) -> Keyword {
|
|
||||||
match value.as_array() {
|
|
||||||
None => vec![vec![]],
|
|
||||||
Some(or_vec) => or_vec
|
|
||||||
.iter()
|
|
||||||
.map(|and_val| match and_val.as_array() {
|
|
||||||
None => vec![],
|
|
||||||
Some(and_vec) => and_vec
|
|
||||||
.iter()
|
|
||||||
.map(|word| word.as_str().unwrap_or_default().to_string())
|
|
||||||
.collect(),
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn json_to_string_list(value: &Value) -> StringList {
|
|
||||||
match value.as_array() {
|
|
||||||
None => vec![],
|
|
||||||
Some(v) => v
|
|
||||||
.iter()
|
|
||||||
.map(|s| s.as_str().unwrap_or_default().to_string())
|
|
||||||
.collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ use model::entity::{antenna, sea_orm_active_enums::AntennaSrcEnum, user};
|
||||||
use sea_orm::{
|
use sea_orm::{
|
||||||
ActiveModelTrait, ActiveValue::Set, DatabaseConnection, DbErr, EntityTrait, TransactionTrait,
|
ActiveModelTrait, ActiveValue::Set, DatabaseConnection, DbErr, EntityTrait, TransactionTrait,
|
||||||
};
|
};
|
||||||
use serde_json::json;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use util::{
|
use util::{
|
||||||
id::{create_id, init_id},
|
id::{create_id, init_id},
|
||||||
|
@ -64,8 +63,16 @@ async fn setup_model(db: &DatabaseConnection) {
|
||||||
user_id: Set(user_id.to_owned()),
|
user_id: Set(user_id.to_owned()),
|
||||||
name: Set("Test Antenna".to_string()),
|
name: Set("Test Antenna".to_string()),
|
||||||
src: Set(AntennaSrcEnum::All),
|
src: Set(AntennaSrcEnum::All),
|
||||||
keywords: Set(json!([["foo", "bar"], ["foobar"]])),
|
keywords: Set(vec![
|
||||||
exclude_keywords: Set(json!([["abc"], ["def", "ghi"]])),
|
vec!["foo".to_string(), "bar".to_string()],
|
||||||
|
vec!["foobar".to_string()],
|
||||||
|
]
|
||||||
|
.into()),
|
||||||
|
exclude_keywords: Set(vec![
|
||||||
|
vec!["abc".to_string()],
|
||||||
|
vec!["def".to_string(), "ghi".to_string()],
|
||||||
|
]
|
||||||
|
.into()),
|
||||||
with_file: Set(false),
|
with_file: Set(false),
|
||||||
notify: Set(true),
|
notify: Set(true),
|
||||||
case_sensitive: Set(true),
|
case_sensitive: Set(true),
|
||||||
|
|
|
@ -38,16 +38,18 @@ mod it_test {
|
||||||
keywords: vec![
|
keywords: vec![
|
||||||
vec!["foo".to_string(), "bar".to_string()],
|
vec!["foo".to_string(), "bar".to_string()],
|
||||||
vec!["foobar".to_string()]
|
vec!["foobar".to_string()]
|
||||||
],
|
]
|
||||||
|
.into(),
|
||||||
exclude_keywords: vec![
|
exclude_keywords: vec![
|
||||||
vec!["abc".to_string()],
|
vec!["abc".to_string()],
|
||||||
vec!["def".to_string(), "ghi".to_string()]
|
vec!["def".to_string(), "ghi".to_string()]
|
||||||
],
|
]
|
||||||
|
.into(),
|
||||||
src: schema::antenna::AntennaSrc::All,
|
src: schema::antenna::AntennaSrc::All,
|
||||||
user_list_id: None,
|
user_list_id: None,
|
||||||
user_group_id: None,
|
user_group_id: None,
|
||||||
users: vec![],
|
users: vec![].into(),
|
||||||
instances: vec![],
|
instances: vec![].into(),
|
||||||
case_sensitive: true,
|
case_sensitive: true,
|
||||||
notify: true,
|
notify: true,
|
||||||
with_replies: false,
|
with_replies: false,
|
||||||
|
|
Loading…
Reference in a new issue