Skip to content

Commit

Permalink
Merge pull request #4230 from valkrypton/feat/add/json_object
Browse files Browse the repository at this point in the history
implement json_object
  • Loading branch information
weiznich authored Sep 10, 2024
2 parents 1b728d2 + 24612ba commit f78e6b8
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 2 deletions.
15 changes: 14 additions & 1 deletion diesel/src/pg/expression/expression_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
pub(in crate::pg) use self::private::{
ArrayOrNullableArray, InetOrCidr, JsonIndex, JsonOrNullableJsonOrJsonbOrNullableJsonb,
JsonRemoveIndex, JsonbOrNullableJsonb, MaybeNullableValue, MultirangeOrNullableMultirange,
MultirangeOrRangeMaybeNullable, RangeHelper, RangeOrNullableRange, TextOrNullableText,
MultirangeOrRangeMaybeNullable, RangeHelper, RangeOrNullableRange,
TextArrayOrNullableTextArray, TextOrNullableText,
};
use super::date_and_time::{AtTimeZone, DateTimeLike};
use super::operators::*;
Expand Down Expand Up @@ -3712,4 +3713,16 @@ pub(in crate::pg) mod private {
{
type Out = <T::IsNull as MaybeNullableType<O>>::Out;
}

#[diagnostic::on_unimplemented(
message = "`{Self}` is neither `Array<Text>`, `Array<Nullable<Text>>`,\
`Nullable<Array<Text>>` nor `diesel::sql_types::Nullable<Array<Nullable<Text>>>`",
note = "try to provide an expression that produces one of the expected sql types"
)]
pub trait TextArrayOrNullableTextArray {}

impl TextArrayOrNullableTextArray for Array<Text> {}
impl TextArrayOrNullableTextArray for Array<Nullable<Text>> {}
impl TextArrayOrNullableTextArray for Nullable<Array<Text>> {}
impl TextArrayOrNullableTextArray for Nullable<Array<Nullable<Text>>> {}
}
46 changes: 46 additions & 0 deletions diesel/src/pg/expression/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::pg::expression::expression_methods::MaybeNullableValue;
use crate::pg::expression::expression_methods::MultirangeOrNullableMultirange;
use crate::pg::expression::expression_methods::MultirangeOrRangeMaybeNullable;
use crate::pg::expression::expression_methods::RangeOrNullableRange;
use crate::pg::expression::expression_methods::TextArrayOrNullableTextArray;
use crate::sql_types::*;

define_sql_function! {
Expand Down Expand Up @@ -1588,3 +1589,48 @@ define_sql_function! {
/// ```
fn to_jsonb<E: MaybeNullableValue<Jsonb>>(e: E) -> E::Out;
}

define_sql_function! {
/// Builds a JSON object out of a text array. The array must have an even number of members,
/// in which case they are taken as alternating key/value pairs
///
/// # Example
///
/// ```rust
/// # include!("../../doctest_setup.rs");
/// #
/// # fn main() {
/// # run_test().unwrap();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use diesel::dsl::json_object;
/// # use diesel::sql_types::{Array, Json, Nullable, Text};
/// # use serde_json::Value;
/// # let connection = &mut establish_connection();
/// let json = diesel::select(json_object::<Array<Text>,_>(vec!["hello","world"]))
/// .get_result::<Value>(connection)?;
/// let expected:Value = serde_json::json!({"hello":"world"});
/// assert_eq!(expected,json);
///
/// let json = diesel::select(json_object::<Array<Text>,_>(vec!["hello","world","John","Doe"]))
/// .get_result::<Value>(connection)?;
/// let expected:Value = serde_json::json!({"hello":"world","John":"Doe"});
/// assert_eq!(expected,json);
///
/// let json = diesel::select(json_object::<Array<Text>,_>(vec!["hello","world","John"]))
/// .get_result::<Value>(connection);
/// assert!(json.is_err());
///
/// let empty:Vec<String> = Vec::new();
/// let json = diesel::select(json_object::<Array<Nullable<Text>>,_>(empty))
/// .get_result::<Value>(connection);
/// assert!(json.is_err());
///
/// # Ok(())
/// # }
/// ```
fn json_object<Arr: TextArrayOrNullableTextArray + MaybeNullableValue<Json>>(
text_array: Arr,
) -> Arr::Out;
}
5 changes: 5 additions & 0 deletions diesel/src/pg/expression/helper_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,3 +481,8 @@ pub type to_json<E> = super::functions::to_json<SqlTypeOf<E>, E>;
#[allow(non_camel_case_types)]
#[cfg(feature = "postgres_backend")]
pub type to_jsonb<E> = super::functions::to_jsonb<SqlTypeOf<E>, E>;

/// Return type of [`json_object(text_array)`](super::functions::json_object())
#[allow(non_camel_case_types)]
#[cfg(feature = "postgres_backend")]
pub type json_object<A> = super::functions::json_object<SqlTypeOf<A>, A>;
4 changes: 3 additions & 1 deletion diesel_derives/tests/auto_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ table! {
range -> Range<Integer>,
multirange -> Multirange<Integer>,
timestamptz -> Timestamptz,
name -> Text
name -> Text,
text_array -> Array<Text>
}
}

Expand Down Expand Up @@ -436,6 +437,7 @@ fn postgres_functions() -> _ {
array_sample(pg_extras::array, pg_extras::id),
to_json(pg_extras::id),
to_jsonb(pg_extras::id),
json_object(pg_extras::text_array),
)
}

Expand Down

0 comments on commit f78e6b8

Please sign in to comment.