rust/hg-core/src/config/config.rs
author Raphaël Gomès <rgomes@octobus.net>
Tue, 29 Dec 2020 10:53:45 +0100
changeset 46187 95d6f31e88db
child 46446 1dcd9c9975ed
permissions -rw-r--r--
hg-core: add basic config module The config module exposes a `Config` struct, unused for now. It only reads the config file local to the repository, but handles all valid patterns and includes/unsets. It is structured in layers instead of erasing by reverse order of precedence, allowing us to transparently know more about the config for debugging purposes, and potentially other things I haven't thought about yet. This change also introduces `format_bytes!` to `hg-core`. Differential Revision: https://phab.mercurial-scm.org/D9408
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
46187
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     1
// config.rs
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     2
//
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     3
// Copyright 2020
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     4
//      Valentin Gatien-Baron,
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     5
//      Raphaël Gomès <rgomes@octobus.net>
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     6
//
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     7
// This software may be used and distributed according to the terms of the
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     8
// GNU General Public License version 2 or any later version.
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     9
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    10
use super::layer;
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    11
use crate::config::layer::{ConfigError, ConfigLayer, ConfigValue};
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    12
use std::path::PathBuf;
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    13
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    14
use crate::operations::find_root;
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    15
use crate::utils::files::read_whole_file;
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    16
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    17
/// Holds the config values for the current repository
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    18
/// TODO update this docstring once we support more sources
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    19
pub struct Config {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    20
    layers: Vec<layer::ConfigLayer>,
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    21
}
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    22
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    23
impl std::fmt::Debug for Config {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    24
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    25
        for (index, layer) in self.layers.iter().rev().enumerate() {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    26
            write!(
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    27
                f,
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    28
                "==== Layer {} (trusted: {}) ====\n{:?}",
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    29
                index, layer.trusted, layer
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    30
            )?;
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    31
        }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    32
        Ok(())
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    33
    }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    34
}
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    35
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    36
pub enum ConfigSource {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    37
    /// Absolute path to a config file
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    38
    AbsPath(PathBuf),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    39
    /// Already parsed (from the CLI, env, Python resources, etc.)
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    40
    Parsed(layer::ConfigLayer),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    41
}
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    42
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    43
pub fn parse_bool(v: &[u8]) -> Option<bool> {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    44
    match v.to_ascii_lowercase().as_slice() {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    45
        b"1" | b"yes" | b"true" | b"on" | b"always" => Some(true),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    46
        b"0" | b"no" | b"false" | b"off" | b"never" => Some(false),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    47
        _ => None,
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    48
    }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    49
}
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    50
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    51
impl Config {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    52
    /// Loads in order, which means that the precedence is the same
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    53
    /// as the order of `sources`.
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    54
    pub fn load_from_explicit_sources(
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    55
        sources: Vec<ConfigSource>,
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    56
    ) -> Result<Self, ConfigError> {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    57
        let mut layers = vec![];
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    58
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    59
        for source in sources.into_iter() {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    60
            match source {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    61
                ConfigSource::Parsed(c) => layers.push(c),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    62
                ConfigSource::AbsPath(c) => {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    63
                    // TODO check if it should be trusted
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    64
                    // mercurial/ui.py:427
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    65
                    let data = match read_whole_file(&c) {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    66
                        Err(_) => continue, // same as the python code
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    67
                        Ok(data) => data,
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    68
                    };
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    69
                    layers.extend(ConfigLayer::parse(&c, &data)?)
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    70
                }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    71
            }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    72
        }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    73
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    74
        Ok(Config { layers })
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    75
    }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    76
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    77
    /// Loads the local config. In a future version, this will also load the
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    78
    /// `$HOME/.hgrc` and more to mirror the Python implementation.
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    79
    pub fn load() -> Result<Self, ConfigError> {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    80
        let root = find_root().unwrap();
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    81
        Ok(Self::load_from_explicit_sources(vec![
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    82
            ConfigSource::AbsPath(root.join(".hg/hgrc")),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    83
        ])?)
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    84
    }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    85
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    86
    /// Returns an `Err` if the first value found is not a valid boolean.
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    87
    /// Otherwise, returns an `Ok(option)`, where `option` is the boolean if
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    88
    /// found, or `None`.
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    89
    pub fn get_option(
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    90
        &self,
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    91
        section: &[u8],
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    92
        item: &[u8],
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    93
    ) -> Result<Option<bool>, ConfigError> {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    94
        match self.get_inner(&section, &item) {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    95
            Some((layer, v)) => match parse_bool(&v.bytes) {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    96
                Some(b) => Ok(Some(b)),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    97
                None => Err(ConfigError::Parse {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    98
                    origin: layer.origin.to_owned(),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    99
                    line: v.line,
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   100
                    bytes: v.bytes.to_owned(),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   101
                }),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   102
            },
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   103
            None => Ok(None),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   104
        }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   105
    }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   106
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   107
    /// Returns the corresponding boolean in the config. Returns `Ok(false)`
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   108
    /// if the value is not found, an `Err` if it's not a valid boolean.
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   109
    pub fn get_bool(
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   110
        &self,
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   111
        section: &[u8],
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   112
        item: &[u8],
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   113
    ) -> Result<bool, ConfigError> {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   114
        Ok(self.get_option(section, item)?.unwrap_or(false))
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   115
    }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   116
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   117
    /// Returns the raw value bytes of the first one found, or `None`.
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   118
    pub fn get(&self, section: &[u8], item: &[u8]) -> Option<&[u8]> {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   119
        self.get_inner(section, item)
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   120
            .map(|(_, value)| value.bytes.as_ref())
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   121
    }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   122
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   123
    /// Returns the layer and the value of the first one found, or `None`.
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   124
    fn get_inner(
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   125
        &self,
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   126
        section: &[u8],
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   127
        item: &[u8],
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   128
    ) -> Option<(&ConfigLayer, &ConfigValue)> {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   129
        for layer in self.layers.iter().rev() {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   130
            if !layer.trusted {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   131
                continue;
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   132
            }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   133
            if let Some(v) = layer.get(&section, &item) {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   134
                return Some((&layer, v));
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   135
            }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   136
        }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   137
        None
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   138
    }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   139
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   140
    /// Get raw values bytes from all layers (even untrusted ones) in order
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   141
    /// of precedence.
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   142
    #[cfg(test)]
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   143
    fn get_all(&self, section: &[u8], item: &[u8]) -> Vec<&[u8]> {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   144
        let mut res = vec![];
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   145
        for layer in self.layers.iter().rev() {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   146
            if let Some(v) = layer.get(&section, &item) {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   147
                res.push(v.bytes.as_ref());
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   148
            }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   149
        }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   150
        res
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   151
    }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   152
}
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   153
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   154
#[cfg(test)]
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   155
mod tests {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   156
    use super::*;
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   157
    use pretty_assertions::assert_eq;
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   158
    use std::fs::File;
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   159
    use std::io::Write;
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   160
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   161
    #[test]
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   162
    fn test_include_layer_ordering() {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   163
        let tmpdir = tempfile::tempdir().unwrap();
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   164
        let tmpdir_path = tmpdir.path();
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   165
        let mut included_file =
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   166
            File::create(&tmpdir_path.join("included.rc")).unwrap();
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   167
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   168
        included_file.write_all(b"[section]\nitem=value1").unwrap();
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   169
        let base_config_path = tmpdir_path.join("base.rc");
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   170
        let mut config_file = File::create(&base_config_path).unwrap();
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   171
        let data =
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   172
            b"[section]\nitem=value0\n%include included.rc\nitem=value2";
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   173
        config_file.write_all(data).unwrap();
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   174
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   175
        let sources = vec![ConfigSource::AbsPath(base_config_path)];
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   176
        let config = Config::load_from_explicit_sources(sources)
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   177
            .expect("expected valid config");
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   178
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   179
        dbg!(&config);
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   180
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   181
        let (_, value) = config.get_inner(b"section", b"item").unwrap();
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   182
        assert_eq!(
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   183
            value,
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   184
            &ConfigValue {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   185
                bytes: b"value2".to_vec(),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   186
                line: Some(4)
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   187
            }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   188
        );
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   189
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   190
        let value = config.get(b"section", b"item").unwrap();
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   191
        assert_eq!(value, b"value2",);
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   192
        assert_eq!(
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   193
            config.get_all(b"section", b"item"),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   194
            [b"value2", b"value1", b"value0"]
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   195
        );
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   196
    }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   197
}