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
use ::sensor::{
    SensorList,
    MetzConnectCI4,
    RaGasCONO2Mod,
    SensorType,
    TestSensor,
};
use config::Config;
use error::ServerError;
use std::fs::File;
use std::io::prelude::*;
use std::path::PathBuf;
use std::sync::{Arc, RwLock};
use toml;


/// Server Representation zum Speichern/ Wiederherstellen einer Konfigurationsdatei
///
#[derive(Debug, Deserialize)]
pub struct Server {
    pub service_interval: u32,
    pub sensors: Vec<::configuration::sensor::Sensor>,
    #[serde(skip)]
    pub configuration_path: Option<PathBuf>,
    #[serde(skip)]
    pub runtime_info_path: Option<PathBuf>,
}

impl Server {
    /// Bildet eine Server Instanz aus der Konfigurationsdatei
    ///
    /// Die Funktion liefert ein `Result` mit einer `::configuration::Server` Instanz, oder liefert ein
    /// `ServerError`.
    ///
    pub fn from_config_file(cfg: &Config) -> Result<Server, ServerError> {
        let mut file = File::open(&cfg.configuration_path)?;
        let mut s = String::new();
        file.read_to_string(&mut s)?;

        match toml::from_str::<Server>(&s) {
            Ok(mut builder) => {
                // Die Pfade zur Konfigurationsdatei und Laufzeitinformation stammen aus dem `Config` Modul.
                // Sie stehen nicht in der Konfigurationsdatei selbst.
                builder.configuration_path = Some(cfg.configuration_path.clone());
                builder.runtime_info_path = Some(cfg.runtime_info_path.clone());
                Ok(builder)
            }
            Err(err) => Err(ServerError::CouldNotBuildFromConfig(err)),
        }
    }
}

/// Konvertierung des `configuration::Server` nach `server::Server`
///
/// Stellt den `server::Server` aus den Daten der Konfigurationsdatei wieder her.
///
impl From<Server> for ::server::Server {
    fn from(server: Server) -> Self {
        // Restauriere Sensoren
        let mut sensors: SensorList = vec![];
        for s in server.sensors {
            match s.sensor_type {
                SensorType::RaGasCONO2Mod => {
                    let sensor: RaGasCONO2Mod = s.into();
                    sensors.push(Arc::new(RwLock::new(Box::new(sensor))));
                },
                SensorType::MetzConnectCI4 => {
                    let sensor: MetzConnectCI4 = s.into();
                    sensors.push(Arc::new(RwLock::new(Box::new(sensor))));
                },
                SensorType::TestSensor => {
                    let sensor: TestSensor = s.into();
                    sensors.push(Arc::new(RwLock::new(Box::new(sensor))));
                },
            }
        }
        ::server::Server {
            service_interval: server.service_interval,
            sensors:  sensors,
            // zones: vec![],
            configuration_path: server.configuration_path,
            runtime_info_path: server.runtime_info_path,
        }
    }
}