Repository: diesel-rs/diesel
File: diesel/src/pg/expression/functions.rs (Rust)

Code before:
    /// #     use diesel::dsl::jsonb_strip_nulls;
    /// #     use diesel::sql_types::{Jsonb, Nullable};
    /// #     use serde_json::{json, Value};
    /// #     let connection = &mut establish_connection();
    ///
    /// let result = diesel::select(jsonb_strip_nulls::<Jsonb, _>(json!({"hello": null})))
    ///     .get_result::<Value>(connection)?;
    /// let expected: Value = json!({});
    /// assert_eq!(result, expected);
    ///
    /// let result = diesel::select(jsonb_strip_nulls::<Jsonb, _>(json!([{"f1":1, "f2":null}, 2, null, 3])))
    ///     .get_result::<Value>(connection)?;
    /// let expected: Value = json!([{"f1":1}, 2, null, 3]);
    /// assert_eq!(result, expected);
    ///
    /// let result = diesel::select(jsonb_strip_nulls::<Jsonb, _>(json!(null)))
    ///     .get_result::<Value>(connection)?;
    /// let expected = json!(null);
    /// assert_eq!(result, expected);
    ///
    ///
    ///
    /// #     Ok(())
    /// # }
    /// ```
    fn jsonb_strip_nulls<E: MaybeNullableValue<Jsonb>>(jsonb: E) -> E::Out;
}


Review comment (refactor):
We need to restrict the generic type `E` here to be either `Jsonb` or `Nullable<Jsonb>`. Also as we return the same output type as input type we don't need the `MaybeNullableValue<Jsonb>` helper type:

```suggestion
    fn jsonb_strip_nulls<E: JsonbOrNullableJsonb>(jsonb: E) -> E;
```

Code after:
    ///
    /// let result = diesel::select(json_typeof::<Json, _>(json!(-123.4)))
    ///     .get_result::<String>(connection)?;
    ///
    /// assert_eq!("number".to_string(), result);
    ///
    /// let result = diesel::select(json_typeof::<Json, _>(json!(true)))
    ///     .get_result::<String>(connection)?;
    ///
    /// assert_eq!("boolean".to_string(), result);
    ///
    /// let result = diesel::select(json_typeof::<Json, _>(json!(null)))
    ///     .get_result::<String>(connection)?;
    ///
    /// assert_eq!("null".to_string(), result);
    ///
    /// let result = diesel::select(json_typeof::<Nullable<Json>, _>(None::<Value>))
    ///     .get_result::<Option<String>>(connection)?;
    ///
    /// assert!(result.is_none());
    /// #     Ok(())
    /// # }
    /// ```
    fn json_typeof<E: JsonOrNullableJson + SingleValue + MaybeNullableValue<Text>>(e: E) -> E::Out;
}

#[cfg(feature = "postgres_backend")]
define_sql_function! {
    /// Returns the type of the top-level jsonb value as a text-string
    ///
    /// # Example
    ///
    /// ```rust
    /// # include!("../../doctest_setup.rs");
    /// #
    /// # fn main() {
    /// #     #[cfg(feature = "serde_json")]
    /// #     run_test().unwrap();
    /// # }
    /// #
    /// # #[cfg(feature = "serde_json")]
    /// # fn run_test() -> QueryResult<()> {
    /// #     use diesel::dsl::jsonb_typeof;
    /// #     use serde_json::{json, Value};
    /// #     use diesel::sql_types::{Jsonb, Nullable};
    /// #     let connection = &mut establish_connection();
    /// let result = diesel::select(jsonb_typeof::<Jsonb, _>(json!({"a": "b", "c": 1})))
    ///     .get_result::<String>(connection)?;
    ///
    /// assert_eq!("object".to_string(), result);
    ///