ruma_common/canonical_json/macros.rs
1/// Asserts that the canonical JSON serialization of a type is equal to an expected JSON value.
2///
3/// By calling [`to_canonical_value()`] internally this macro enforces strict serialization rules
4/// which allows to avoid some pitfalls like having a [`serde::Serialize`] implementation that
5/// generates the same key twice in an object, which is ignored by [`serde_json::to_value()`].
6///
7/// The expression on the left is the one whose serialization needs to be checked. It must
8/// implement [`serde::Serialize`], and is serialized using [`to_canonical_value()`].
9///
10/// The expression on the right is the expected JSON serialization as a [`serde_json::Value`]. It is
11/// usually a declaration using the [`serde_json::json!`] macro. It is then converted to a
12/// [`CanonicalJsonValue`] and compared with the result of the serialization of the expression on
13/// the left.
14///
15/// Panics if the expression on the left fails to serialize, if the expected JSON fails to be
16/// converted to a [`CanonicalJsonValue`], or if the two values are not equal.
17///
18/// This macro will print the error if the serialization or the conversion fails, or both debug
19/// representations of the [`CanonicalJsonValue`]s if they are not equal.
20///
21/// ## Example
22///
23/// ```
24/// use ruma_common::canonical_json::assert_to_canonical_json_eq;
25/// use serde::Serialize;
26/// use serde_json::json;
27///
28/// #[derive(Serialize)]
29/// struct Data {
30/// id: String,
31/// flag: bool,
32/// }
33///
34/// let data = Data { id: "abcdef".to_owned(), flag: true };
35/// assert_to_canonical_json_eq!(data, json!({ "id": "abcdef", "flag": true }));
36/// ```
37///
38/// [`CanonicalJsonValue`]: super::CanonicalJsonValue
39/// [`to_canonical_value()`]: super::to_canonical_value
40#[doc(hidden)]
41#[macro_export]
42macro_rules! assert_to_canonical_json_eq {
43 ($left:expr, $right:expr $(,)?) => {
44 let left_val =
45 $crate::canonical_json::to_canonical_value(&$left).expect("left serialization failed");
46 let right_val = <serde_json::Value as TryInto<
47 $crate::canonical_json::CanonicalJsonValue,
48 >>::try_into($right)
49 .expect("right conversion failed");
50 assert_eq!(left_val, right_val);
51 };
52}