sensors/
sensors.rs

1//! I have group of options which could be used multiple times. All such groups should be kept without overwriting previous one.
2//!
3//! $ prometheus_sensors_exporter \
4//!     \
5//!     `# 2 physical sensors located on physycial different i2c bus or address` \
6//!     --sensor \
7//!         --sensor-device=tmp102 \
8//!         --sensor-name="temperature_tmp102_outdoor" \
9//!         --sensor-i2c-bus=0 \
10//!         --sensor-i2c-address=0x48 \
11//!     --sensor \
12//!         --sensor-device=tmp102 \
13//!         --sensor-name="temperature_tmp102_indoor" \
14//!         --sensor-i2c-bus=1 \
15//!         --sensor-i2c-address=0x49 \
16
17use bpaf::*;
18#[allow(dead_code)]
19#[derive(Debug, Clone)]
20struct Sensor {
21    sensor: (),
22    device: String,
23    name: String,
24    bus_id: usize,
25    address: usize,
26}
27
28#[allow(dead_code)]
29#[derive(Debug, Clone)]
30struct Opts {
31    sensors: Vec<Sensor>,
32}
33
34// generates completion suggestions
35fn sensor_device_comp(input: &String) -> Vec<(String, Option<String>)> {
36    [
37        ("temp100", "Main temperature sensor"),
38        ("temp101", "Output temperature sensor"),
39        ("tank01", "Temperature in a storage tank 1"),
40        ("tank02", "Temperature in a storage tank 2"),
41        ("tank03", "Temperature in a storage tank 3"),
42        ("outdoor", "Outdoor temperature sensor"),
43    ]
44    .iter()
45    .filter_map(|(name, descr)| {
46        if name.starts_with(input) {
47            Some((name.to_string(), Some(descr.to_string())))
48        } else {
49            None
50        }
51    })
52    .collect::<Vec<_>>()
53}
54
55fn opts() -> Opts {
56    let sensor = long("sensor").req_flag(());
57    let device = long("sensor-device")
58        .argument::<String>("DEVICE")
59        .complete(sensor_device_comp);
60    let name = long("sensor-name").argument::<String>("NAME");
61
62    // from_str needs to be replaced with `parse` that can deal with hex digits
63    let bus_id = long("sensor-i2c-bus").argument::<usize>("BUS");
64    let address = long("sensor-i2c-address").argument::<usize>("ADDRESS");
65    let sensors = construct!(Sensor {
66        sensor,
67        device,
68        name,
69        bus_id,
70        address
71    })
72    .adjacent()
73    .many();
74    construct!(Opts { sensors }).to_options().run()
75}
76
77fn main() {
78    println!("{:#?}", opts());
79}