Rust-Programming-Cookbook/Chapter09/reading-hardware/src/sensor.rs

62 wiersze
1.4 KiB
Rust

use std::io;
use rand::prelude::*;
type Result<T> = std::result::Result<T, io::Error>;
pub trait Thermometer {
fn temp_celsius(&mut self) -> Result<f32>;
}
#[allow(dead_code)]
pub struct RawI2CDeviceMock {
path: String,
device_id: u8,
}
enum Register {
Calib0 = 0x00,
Data = 0x01,
}
impl RawI2CDeviceMock {
pub fn new(path: String, device_id: u8) -> RawI2CDeviceMock {
RawI2CDeviceMock {
path: path,
device_id: device_id,
}
}
pub fn read(&self, register: u8) -> Result<u8> {
let register = register as usize;
if register == Register::Calib0 as usize {
Ok(1_u8)
} else { // register is the data register
Ok(random::<u8>())
}
}
}
pub struct Bmx42Device {
raw: RawI2CDeviceMock,
calibration: u8,
}
impl Bmx42Device {
pub fn new(device: RawI2CDeviceMock) -> Result<Bmx42Device> {
let calib = device.read(Register::Calib0 as u8)?;
Ok(Bmx42Device {
raw: device,
calibration: calib
})
}
}
impl Thermometer for Bmx42Device {
fn temp_celsius(&mut self) -> Result<f32> {
let raw_temp = self.raw.read(Register::Data as u8)?;
// converts the result into something usable; from the specification
Ok(((raw_temp as i8) << (self.calibration as i8)) as f32 / 10.0)
}
}