Reputation: 19442
I have a list of sensor specifications. Each sensor type has an accompanying struct. A sensor spec has a sensor type and a key with which the data can be fetched from the database as a string.
Depending on the sensor type, the data should be converted into a numeric value, could be something like u8 or f64.
Here's an example:
use std::collections::HashMap;
struct SensorSpec {
sensor_type: SensorType,
data_key: String,
}
enum SensorType {
A,
B,
}
#[derive(Debug)]
struct SensorA {
value: u8,
}
#[derive(Debug)]
struct SensorB {
value: f64,
}
fn main() {
// This simulates the database
let mut db: HashMap<String, String> = HashMap::new();
db.insert("a".to_string(), "42".to_string());
db.insert("b".to_string(), "13.37".to_string());
// List of sensors
let mut sensor_specs: Vec<SensorSpec> = vec![
SensorSpec { sensor_type: SensorType::A, data_key: "a".to_string() },
SensorSpec { sensor_type: SensorType::B, data_key: "b".to_string() },
];
for sensor in sensor_specs {
// 1. Fetch data as string from db
// 2. Convert it according to the sensor type
// 3. Print sensor object to terminal
let val = db.get(&sensor.data_key);
let s = match sensor.sensor_type {
SensorType::A => {
SensorA { value: val }
},
SensorType::B => {
SensorB { value: val }
},
};
println!("{:?}", s);
}
}
There are two problems with this:
Here's the compile message for #2:
example.rs:43:17: 50:10 error: match arms have incompatible types:
expected `SensorA`,
found `SensorB`
How can I solve this issue?
Upvotes: 0
Views: 644
Reputation: 19742
I'd replace your SensorType
enum with the following one:
enum Sensor {
A(SensorA),
B(SensorB)
}
This has the advantage that you can put both classes of Sensor
in the same container:
let sensorA = ...;
let sensorB = ...;
let mut vec = vec!( Sensor::A( sensorA ), Sensor::B( sensorB ) );
Or write your own functions that expect either class of Sensor
:
fn use_sensor( sensor: &Sensor ) {
match sensor {
Sensor::A( sensorA ) => sensorA.foo(),
Sensor::B( sensorB ) => sensorB.bar()
}
}
Upvotes: 1