hglib/
builder.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this file,
3// You can obtain one at http://mozilla.org/MPL/2.0/.
4
5pub trait MkArg<'a> {
6    fn mk(&self, option: &'a str, args: &mut Vec<&'a str>) -> Option<String>;
7}
8
9impl<'a> MkArg<'a> for bool {
10    fn mk(&self, option: &'a str, args: &mut Vec<&'a str>) -> Option<String> {
11        if *self {
12            args.push(option);
13        }
14        None
15    }
16}
17
18impl<'a, T: std::string::ToString> MkArg<'a> for Option<T> {
19    fn mk(&self, _option: &'a str, _args: &mut Vec<&'a str>) -> Option<String> {
20        if let Some(x) = self {
21            Some(x.to_string())
22        } else {
23            None
24        }
25    }
26}
27
28impl<'a> MkArg<'a> for u32 {
29    fn mk(&self, _option: &'a str, _args: &mut Vec<&'a str>) -> Option<String> {
30        Some(self.to_string())
31    }
32}
33
34impl<'a> MkArg<'a> for &'a [&'a str] {
35    fn mk(&self, option: &'a str, args: &mut Vec<&'a str>) -> Option<String> {
36        for v in *self {
37            if !v.is_empty() {
38                args.push(option);
39                args.push(&v);
40            }
41        }
42        None
43    }
44}
45
46impl<'a> MkArg<'a> for &'a str {
47    fn mk(&self, option: &'a str, args: &mut Vec<&'a str>) -> Option<String> {
48        if !self.is_empty() {
49            args.push(option);
50            args.push(self);
51        }
52        None
53    }
54}
55
56macro_rules! fn_array {
57    ($N: expr) => {
58        impl<'a> MkArg<'a> for &'a [&'a str; $N] {
59            fn mk(&self, option: &'a str, args: &mut Vec<&'a str>) -> Option<String> {
60                for v in *self {
61                    if !v.is_empty() {
62                        args.push(option);
63                        args.push(&v);
64                    }
65                }
66                None
67            }
68        }
69    };
70}
71
72// In waiting for generics with const values
73fn_array!(1);
74fn_array!(2);
75fn_array!(3);
76fn_array!(4);
77fn_array!(5);
78fn_array!(6);
79fn_array!(7);
80fn_array!(8);
81fn_array!(9);
82fn_array!(10);
83fn_array!(11);
84fn_array!(12);
85fn_array!(13);
86fn_array!(14);
87fn_array!(15);
88fn_array!(16);
89
90#[macro_export]
91macro_rules! debug_vec {
92    ($v: expr) => {{
93        let tmp: Vec<char> = $v.iter().map(|x| *x as char).collect();
94        println!("DEBUG {}: {:?}", stringify!($v), tmp);
95    }};
96}
97
98#[macro_export]
99macro_rules! hg {
100    ($client: expr, $com: ident $(, $a: ident = $v: expr)* ) => {{
101        #![allow(clippy::needless_update)]
102        $client.$com($com::Arg {
103            $(
104                $a: $v,
105            )*
106            ..Default::default()
107        })
108      }}
109}
110
111#[macro_export]
112macro_rules! HG {
113    ($client: ident $(, $a: ident = $v: expr)* ) => {{
114        #![allow(clippy::needless_update)]
115        $client::Arg {
116            $(
117                $a: $v,
118            )*
119            ..Default::default()
120        }.run(&mut Basic { })
121      }}
122}
123
124#[macro_export]
125macro_rules! runcommand {
126    ( $client: expr, $name: expr, $args: expr $(, $o: expr, $x: expr )* ) => {{
127        let mut tmp = Vec::new();
128        tmp.push($name);
129        $(
130            let v = if let Some(s) = $x.mk($o, &mut tmp) {
131                s
132            } else {
133                String::new()
134            };
135            if !v.is_empty() {
136                tmp.push($o);
137                tmp.push(&v);
138            }
139        )*
140        if !$args.is_empty() {
141            tmp.push("--");
142            for arg in $args {
143                if !arg.is_empty() {
144                    tmp.push(arg);
145                }
146            }
147        }
148        $client.runcommand(&tmp, None)
149    }};
150}
151
152#[macro_export]
153macro_rules! runcommand_with_prompt {
154    ( $client: expr, $name: expr, $prompt: expr, $args: expr $(, $o: expr, $x: expr )* ) => {{
155        let mut tmp = Vec::new();
156        tmp.push($name);
157        $(
158            let v = if let Some(s) = $x.mk($o, &mut tmp) {
159                s
160            } else {
161                String::new()
162            };
163            if !v.is_empty() {
164                tmp.push($o);
165                tmp.push(&v);
166            }
167        )*
168        if !$args.is_empty() {
169            for arg in $args {
170                if !arg.is_empty() {
171                    tmp.push(arg);
172                }
173            }
174        }
175        $client.runcommand(&tmp, Some(Box::new($prompt)))
176    }};
177}