Skip to main content

argos_arpa/
config.rs

1//! This module contains configuration that should ideally be loaded from a
2//! file. It is subdivided into categories.
3//!
4//! [`crate::Archivist`] calls [`Config::load`] upon creation, so it should all be
5//! automatic.
6
7use std::path::Path;
8
9use crate::ARPAError;
10use serde::{Deserialize, Serialize};
11
12#[derive(Deserialize, Serialize)]
13/// Supergroup of configuration options.
14pub struct Config {
15    /// Relating to the database connection.
16    pub database: Database,
17    /// Decsribing pipeline behaviour.
18    pub behaviour: Behaviour,
19    /// A collection of paths.
20    pub paths: Paths,
21}
22
23#[derive(Deserialize, Serialize)]
24/// Relating to the database connection.
25pub struct Database {
26    /// Here we use a local postgre server (the postgres app) for testing
27    pub url: String,
28    /// Not too sure on what's a good number here...
29    pub pool_connections: u32,
30    /// 4 seconds is plenty, no? I hope so...
31    pub connection_timeout: u64,
32}
33
34#[allow(clippy::struct_excessive_bools)]
35#[derive(Deserialize, Serialize)]
36/// Decsribing pipeline behaviour.
37pub struct Behaviour {
38    /// Whether to automatically add unregistered encountered pulsars.
39    pub auto_add_pulsars: bool,
40
41    /// If a file is picked, but something with the same checksum is already  
42    /// in the DB, do not thrown an error. Instead, pick the old file.
43    pub auto_resolve_duplicate_uploads: bool,
44
45    /// Which method to use for fitting TOAs.
46    pub toa_fitting: String,
47
48    /// The diagnostics to perform on cooked raw files.
49    pub diagnostics: Vec<String>,
50}
51
52#[derive(Deserialize, Serialize)]
53/// A collection of paths.
54pub struct Paths {
55    /// Path to psrchive executables.
56    pub psrchive: String,
57    /// The root directory for temporary files.
58    pub temp_dir: String,
59    /// The root dir for all diagnostics.
60    pub diagnostics_dir: String,
61}
62
63impl Config {
64    /// Reads config from a `.toml` file.
65    ///
66    /// # Errors
67    /// File can't be read, or file contents don't match config struct.
68    pub fn load(path: impl AsRef<Path>) -> Result<Self, ARPAError> {
69        let data = std::fs::read_to_string(path)?;
70        let config = toml::from_str(&data)?;
71
72        Ok(config)
73    }
74
75    /// Saves the configuration to a file.
76    ///
77    /// # Errors
78    /// Forwarded from `toml` and `std::fs`.
79    pub fn save(&self, path: impl AsRef<Path>) -> Result<(), ARPAError> {
80        let text = toml::to_string(self)?;
81        std::fs::write(path, text)?;
82
83        Ok(())
84    }
85}
86impl Default for Config {
87    /// Provides sensible default settings.
88    /// Note that this does not set paths, however.
89    fn default() -> Self {
90        let database = Database {
91            url: "postgresql://localhost:5437".into(),
92            pool_connections: 4,
93            connection_timeout: 4000,
94        };
95
96        let behaviour = Behaviour {
97            auto_add_pulsars: true,
98            auto_resolve_duplicate_uploads: true,
99            toa_fitting: "FDM".into(),
100            diagnostics: vec!["snr".into(), "composite".into()],
101        };
102
103        let paths = Paths {
104            psrchive: String::new(),
105            temp_dir: String::new(),
106            diagnostics_dir: String::new(),
107        };
108
109        Self {
110            database,
111            behaviour,
112            paths,
113        }
114    }
115}