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
use core::marker::PhantomData;

use embedded_hal_async::{digital::Wait, i2c::I2c};

use crate::{
    person_sensor::{ContinuousCaptureMode, PersonSensorMode, StandbyMode},
    PersonSensor,
};

/// Builder for the PersonSensor driver
///
/// Use this to create a new instance of the PersonSensor driver
pub struct PersonSensorBuilder<I2C, INT, MODE> {
    i2c: I2C,
    interrupt: INT,
    mode: PhantomData<MODE>,
}

impl<I2C> PersonSensorBuilder<I2C, (), ()>
where
    I2C: I2c,
{
    /// Create a new driver instance without an interrupt, initialized in standby mode
    pub fn new_standby(i2c: I2C) -> PersonSensorBuilder<I2C, (), StandbyMode> {
        PersonSensorBuilder {
            i2c,
            interrupt: (),
            mode: PhantomData,
        }
    }

    /// Create a new driver instance without an interrupt, initialized in continuous mode
    pub fn new_continuous(i2c: I2C) -> PersonSensorBuilder<I2C, (), ContinuousCaptureMode> {
        PersonSensorBuilder {
            i2c,
            interrupt: (),
            mode: PhantomData,
        }
    }
}

impl<I2C, MODE> PersonSensorBuilder<I2C, (), MODE>
where
    I2C: I2c,
{
    /// Sets an interrupt pin
    pub fn with_interrupt<INT: Wait>(self, interrupt: INT) -> PersonSensorBuilder<I2C, INT, MODE> {
        PersonSensorBuilder {
            i2c: self.i2c,
            interrupt,
            mode: self.mode,
        }
    }
}

impl<I2C, INT> PersonSensorBuilder<I2C, INT, ContinuousCaptureMode>
where
    I2C: I2c,
{
    /// Initialize the sensor in continuous mode
    pub async fn build(self) -> Result<PersonSensor<I2C, INT, ContinuousCaptureMode>, I2C::Error> {
        let mut sensor = PersonSensor {
            i2c: self.i2c,
            interrupt: self.interrupt,
            mode: PhantomData,
        };
        sensor.set_mode(PersonSensorMode::Continuous).await?;
        Ok(sensor)
    }
}

impl<I2C, INT> PersonSensorBuilder<I2C, INT, StandbyMode>
where
    I2C: I2c,
{
    /// Initialize the sensor in standby mode
    pub async fn build(self) -> Result<PersonSensor<I2C, INT, StandbyMode>, I2C::Error> {
        let mut sensor = PersonSensor {
            i2c: self.i2c,
            interrupt: self.interrupt,
            mode: PhantomData,
        };
        sensor.set_mode(PersonSensorMode::Standby).await?;
        Ok(sensor)
    }
}