1use serde::{Deserialize, Deserializer, Serialize, Serializer};
2
3#[derive(Debug)]
8pub struct Arguments<T>(pub T);
9
10impl Serialize for Arguments<()> {
11 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
12 [(); 0].serialize(serializer)
13 }
14}
15
16impl<'de> Deserialize<'de> for Arguments<()> {
17 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
18 <[(); 0]>::deserialize(deserializer)?;
19 Ok(Self(()))
20 }
21}
22
23macro_rules! impl_arguments {
24 ($($t:ident),+ $(,)?) => {
25 impl<$($t: Serialize),+> Serialize for Arguments<($($t,)+)> {
26 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
27 self.0.serialize(serializer)
28 }
29 }
30
31 impl<'de, $($t: Deserialize<'de>),+> Deserialize<'de> for Arguments<($($t,)+)> {
32 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
33 <($($t,)+)>::deserialize(deserializer).map(Self)
34 }
35 }
36 };
37}
38
39impl_arguments!(T1);
40impl_arguments!(T1, T2);
41impl_arguments!(T1, T2, T3);
42impl_arguments!(T1, T2, T3, T4);
43impl_arguments!(T1, T2, T3, T4, T5);
44impl_arguments!(T1, T2, T3, T4, T5, T6);
45impl_arguments!(T1, T2, T3, T4, T5, T6, T7);
46impl_arguments!(T1, T2, T3, T4, T5, T6, T7, T8);
47impl_arguments!(T1, T2, T3, T4, T5, T6, T7, T8, T9);
48impl_arguments!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
49impl_arguments!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
50impl_arguments!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
51
52#[cfg(test)]
53mod tests {
54 use serde_json::{from_str, to_string};
55
56 use super::*;
57 use crate::{Surrogate, Surrogated};
58
59 #[test]
60 fn empty_arguments_and_one_unit_argument_have_distinct_encodings() {
61 assert_eq!(to_string(&Arguments(())).unwrap(), "[]");
62 assert_eq!(to_string(&Arguments(((),))).unwrap(), "[null]");
63 from_str::<Arguments<()>>("[]").unwrap();
64 from_str::<Arguments<((),)>>("[null]").unwrap();
65 assert_eq!(to_string(&()).unwrap(), "null");
66 }
67
68 #[test]
69 fn arguments_require_an_array_of_the_declared_length() {
70 for input in ["null", "{}", "[null]", "[true]"] {
71 assert!(from_str::<Arguments<()>>(input).is_err(), "{input}");
72 }
73 for input in ["null", "true", "[]", "[true, false]", "[1]"] {
74 assert!(from_str::<Arguments<(bool,)>>(input).is_err(), "{input}");
75 }
76 }
77
78 #[test]
79 fn arguments_preserve_each_values_surrogate_encoding() {
80 let value = (42u128, Some(String::from("hello")));
81 let arguments = Arguments(value.clone().into_surrogate());
82 let json = to_string(&arguments).unwrap();
83 assert_eq!(
84 json,
85 r#"[{"t":"u128","bits":128,"v":"42"},{"t":"Option","v":"hello"}]"#,
86 );
87 let decoded: Arguments<<(u128, Option<String>) as Surrogated>::Surrogate> =
88 from_str(&json).unwrap();
89 assert_eq!(decoded.0.into_real(), value);
90 }
91}