1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/// Transposes an arbitrary length of tuple of `Option`s/`Result`s into an `Option`/`Result` of a tuple.
///
/// Syntax:
///
/// - `Option`-variant: `transpose_tuple!(Option; e1, e2, ..., eN)` ... transposes a tuple of `Option`s.
/// - You can omit `Option;` part, like: `transpose_tuple!(e1, e2, ..., eN)`.
/// - `Result`-variant: `transpose_tuple!(Result; e1, e2, ..., eN)`... transposes a tuple of [`valq::Result`]s.
///
/// Note: `Result`-variant is meant to be used with [`valq::Result`] (return type of `query_value_result!` macro).
/// It doesn't support other error types for now.
///
/// [`valq::Result`]: crate::Result
///
/// ## Examples
///
/// ```
/// // Options
/// use serde_json::json;
/// use valq::{query_value, transpose_tuple};
///
/// let valq = json!({
/// "name": "valq",
/// "keywords": ["macro", "query", "serde"],
/// "author": {
/// "name": "jiftechnify",
/// "age": 31
/// }
/// });
///
/// let picks = transpose_tuple!(
/// query_value!(valq.name -> str),
/// query_value!(valq.keywords[1] -> str),
/// query_value!(valq.author.age -> u64),
/// );
/// assert_eq!(picks, Some(("valq", "query", 31u64)));
///
/// let wrong_picks = transpose_tuple!(
/// query_value!(valq.name -> str),
/// query_value!(valq.keywords[10] -> str), // out of bounds
/// );
/// assert_eq!(wrong_picks, None);
/// ```
///
/// ```
/// // Results
/// # use serde_json::json;
/// use valq::{query_value_result, transpose_tuple};
/// # let valq = json!({
/// # "name": "valq",
/// # "keywords": ["macro", "query", "serde"],
/// # "author": {
/// # "name": "jiftechnify",
/// # "age": 31
/// # }
/// # });
///
/// let picks = transpose_tuple!(
/// Result; // don't forget this!
/// query_value_result!(valq.name -> str),
/// query_value_result!(valq.keywords[1] -> str),
/// query_value_result!(valq.author.age -> u64),
/// );
/// assert!(matches!(picks, Ok(("valq", "query", 31u64))));
///
/// let wrong_picks = transpose_tuple!(
/// Result;
/// query_value_result!(valq.name -> str),
/// query_value_result!(valq.secrets), // non-existent path
/// );
/// assert!(matches!(wrong_picks, Err(valq::Error::ValueNotFoundAtPath(_))));
/// ```