glib_signal/
from_values.rs

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) }