Add json_from_sql and json_to_sql macros
This commit is contained in:
parent
536c7ecb21
commit
a9504de10d
6 changed files with 51 additions and 38 deletions
|
@ -184,7 +184,7 @@ pub fn get_local_actor(
|
|||
None => None,
|
||||
};
|
||||
let properties = user.profile.extra_fields.clone()
|
||||
.unpack().into_iter()
|
||||
.into_inner().into_iter()
|
||||
.map(|field| {
|
||||
ActorProperty {
|
||||
object_type: PROPERTY_VALUE.to_string(),
|
||||
|
|
|
@ -19,7 +19,8 @@ macro_rules! int_enum_to_sql {
|
|||
($t:ty) => {
|
||||
impl postgres_types::ToSql for $t {
|
||||
fn to_sql(
|
||||
&self, _: &postgres_types::Type,
|
||||
&self,
|
||||
_: &postgres_types::Type,
|
||||
out: &mut postgres_types::private::BytesMut,
|
||||
) -> Result<postgres_types::IsNull, Box<dyn std::error::Error + Sync + Send>> {
|
||||
let int_value: i16 = self.into();
|
||||
|
|
39
src/database/json_macro.rs
Normal file
39
src/database/json_macro.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
/// Implements FromSql trait for any de-serializable type
|
||||
macro_rules! json_from_sql {
|
||||
($t:ty) => {
|
||||
impl<'a> postgres_types::FromSql<'a> for $t {
|
||||
fn from_sql(
|
||||
ty: &postgres_types::Type,
|
||||
raw: &'a [u8],
|
||||
) -> Result<$t, Box<dyn std::error::Error + Sync + Send>> {
|
||||
let postgres_types::Json(json_value) =
|
||||
postgres_types::Json::<serde_json::Value>::from_sql(ty, raw)?;
|
||||
let value: $t = serde_json::from_value(json_value)?;
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
postgres_types::accepts!(JSON, JSONB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Implements ToSql trait for any serializable type
|
||||
macro_rules! json_to_sql {
|
||||
($t:ty) => {
|
||||
impl postgres_types::ToSql for $t {
|
||||
fn to_sql(
|
||||
&self,
|
||||
ty: &postgres_types::Type,
|
||||
out: &mut postgres_types::private::BytesMut,
|
||||
) -> Result<postgres_types::IsNull, Box<dyn std::error::Error + Sync + Send>> {
|
||||
let value = serde_json::to_value(self)?;
|
||||
postgres_types::Json(value).to_sql(ty, out)
|
||||
}
|
||||
|
||||
postgres_types::accepts!(JSON, JSONB);
|
||||
postgres_types::to_sql_checked!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) use {json_from_sql, json_to_sql};
|
|
@ -3,6 +3,7 @@ use tokio_postgres::error::{Error as PgError, SqlState};
|
|||
use crate::errors::DatabaseError;
|
||||
|
||||
pub mod int_enum;
|
||||
pub mod json_macro;
|
||||
pub mod migrate;
|
||||
pub mod query_macro;
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ impl Account {
|
|||
.map(|name| get_file_url(instance_url, name));
|
||||
let header_url = profile.banner_file_name.as_ref()
|
||||
.map(|name| get_file_url(instance_url, name));
|
||||
let fields = profile.extra_fields.unpack().into_iter()
|
||||
let fields = profile.extra_fields.into_inner().into_iter()
|
||||
.map(|field| AccountField { name: field.name, value: field.value })
|
||||
.collect();
|
||||
Self {
|
||||
|
@ -83,7 +83,7 @@ impl Account {
|
|||
|
||||
pub fn from_user(user: User, instance_url: &str) -> Self {
|
||||
let fields_sources = user.profile.extra_fields.clone()
|
||||
.unpack().into_iter()
|
||||
.into_inner().into_iter()
|
||||
.map(|field| AccountField {
|
||||
name: field.name,
|
||||
value: field.value_source.unwrap_or(field.value),
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
use chrono::{DateTime, Utc};
|
||||
use postgres_types::{
|
||||
FromSql, ToSql, IsNull, Type, Json,
|
||||
accepts, to_sql_checked,
|
||||
private::BytesMut,
|
||||
};
|
||||
use postgres_types::FromSql;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::activitypub::actor::Actor;
|
||||
use crate::activitypub::views::get_actor_url;
|
||||
use crate::database::json_macro::{json_from_sql, json_to_sql};
|
||||
use crate::errors::ValidationError;
|
||||
use super::validators::{
|
||||
validate_username,
|
||||
|
@ -29,7 +26,7 @@ pub struct ExtraField {
|
|||
pub struct ExtraFields(pub Vec<ExtraField>);
|
||||
|
||||
impl ExtraFields {
|
||||
pub fn unpack(self) -> Vec<ExtraField> {
|
||||
pub fn into_inner(self) -> Vec<ExtraField> {
|
||||
let Self(extra_fields) = self;
|
||||
extra_fields
|
||||
}
|
||||
|
@ -39,35 +36,10 @@ pub fn get_currency_field_name(currency_code: &str) -> String {
|
|||
format!("${}", currency_code.to_uppercase())
|
||||
}
|
||||
|
||||
type SqlError = Box<dyn std::error::Error + Sync + Send>;
|
||||
json_from_sql!(ExtraFields);
|
||||
json_to_sql!(ExtraFields);
|
||||
|
||||
impl<'a> FromSql<'a> for ExtraFields {
|
||||
fn from_sql(ty: &Type, raw: &'a [u8]) -> Result<Self, SqlError> {
|
||||
let Json(json_value) = Json::<Value>::from_sql(ty, raw)?;
|
||||
let fields: Self = serde_json::from_value(json_value)?;
|
||||
Ok(fields)
|
||||
}
|
||||
accepts!(JSON, JSONB);
|
||||
}
|
||||
|
||||
impl ToSql for ExtraFields {
|
||||
fn to_sql(&self, ty: &Type, out: &mut BytesMut) -> Result<IsNull, SqlError> {
|
||||
let value = serde_json::to_value(self)?;
|
||||
Json(value).to_sql(ty, out)
|
||||
}
|
||||
|
||||
accepts!(JSON, JSONB);
|
||||
to_sql_checked!();
|
||||
}
|
||||
|
||||
impl<'a> FromSql<'a> for Actor {
|
||||
fn from_sql(ty: &Type, raw: &'a [u8]) -> Result<Self, SqlError> {
|
||||
let Json(json_value) = Json::<Value>::from_sql(ty, raw)?;
|
||||
let actor: Self = serde_json::from_value(json_value)?;
|
||||
Ok(actor)
|
||||
}
|
||||
accepts!(JSON, JSONB);
|
||||
}
|
||||
json_from_sql!(Actor);
|
||||
|
||||
#[derive(Clone, FromSql)]
|
||||
#[postgres(name = "actor_profile")]
|
||||
|
|
Loading…
Reference in a new issue