1use {
2 glib::{
3 types::StaticType,
4 value::{FromValue, ValueTypeChecker, ValueTypeMismatchError, ValueTypeMismatchOrNoneError},
5 Type, Value,
6 },
7 std::error::Error,
8};
9
10pub trait FromValues<'a> {
11 type Error: Error;
12 type Types: IntoIterator<Item = Type>;
13
14 fn from_values(args: &'a [Value]) -> Result<Self, Self::Error>
15 where
16 Self: Sized;
17 fn static_types() -> Self::Types;
18}
19
20macro_rules! impl_signal_arguments {
21 ($count:literal; ($($tx:ident),*)) => {
22 #[allow(non_snake_case)]
23 impl<'a, $($tx,)*> FromValues<'a> for ($($tx, )*) where
24 $($tx: FromValue<'a> + StaticType,)*
25 $(ValueTypeMismatchOrNoneError<ValueTypeMismatchError>: From<<$tx::Checker as ValueTypeChecker>::Error>,)*
26 {
27 type Error = ValueTypeMismatchOrNoneError<ValueTypeMismatchError>;
28 type Types = [Type; $count];
29
30 fn from_values(args: &'a [Value]) -> Result<Self, Self::Error> {
31 match args {
32 [$($tx,)*] => Ok(($($tx.get()?,)*)),
33 _ => Err(ValueTypeMismatchOrNoneError::UnexpectedNone),
34 }
35 }
36
37 fn static_types() -> Self::Types {
38 [$($tx::static_type(),)*]
39 }
40 }
41 };
42}
43
44impl_signal_arguments! { 0; () }
45impl_signal_arguments! { 1; (T0) }
46impl_signal_arguments! { 2; (T0, T1) }
47impl_signal_arguments! { 3; (T0, T1, T2) }
48impl_signal_arguments! { 4; (T0, T1, T2, T3) }
49impl_signal_arguments! { 5; (T0, T1, T2, T3, T4) }
50impl_signal_arguments! { 6; (T0, T1, T2, T3, T4, T5) }
51impl_signal_arguments! { 7; (T0, T1, T2, T3, T4, T5, T6) }
52impl_signal_arguments! { 8; (T0, T1, T2, T3, T4, T5, T6, T7) }
53impl_signal_arguments! { 9; (T0, T1, T2, T3, T4, T5, T6, T7, T8) }
54impl_signal_arguments! { 10; (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) }
55impl_signal_arguments! { 11; (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) }
56impl_signal_arguments! { 12; (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) }