Mercurial > hg
annotate rust/hg-core/src/config/layer.rs @ 46481:0d734c0ae1cf
rust: replace read_whole_file with std::fs::read
It does the same thing
Differential Revision: https://phab.mercurial-scm.org/D9959
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Mon, 01 Feb 2021 12:25:53 +0100 |
parents | 0cb1b02228a6 |
children | 39128182f04e |
rev | line source |
---|---|
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
1 // layer.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 |
46447
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
10 use crate::errors::{HgError, IoResultExt}; |
46481
0d734c0ae1cf
rust: replace read_whole_file with std::fs::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46447
diff
changeset
|
11 use crate::utils::files::{get_bytes_from_path, get_path_from_bytes}; |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
12 use format_bytes::format_bytes; |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
13 use lazy_static::lazy_static; |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
14 use regex::bytes::Regex; |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
15 use std::collections::HashMap; |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
16 use std::io; |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
17 use std::path::{Path, PathBuf}; |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
18 |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
19 lazy_static! { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
20 static ref SECTION_RE: Regex = make_regex(r"^\[([^\[]+)\]"); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
21 static ref ITEM_RE: Regex = make_regex(r"^([^=\s][^=]*?)\s*=\s*((.*\S)?)"); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
22 /// Continuation whitespace |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
23 static ref CONT_RE: Regex = make_regex(r"^\s+(\S|\S.*\S)\s*$"); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
24 static ref EMPTY_RE: Regex = make_regex(r"^(;|#|\s*$)"); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
25 static ref COMMENT_RE: Regex = make_regex(r"^(;|#)"); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
26 /// A directive that allows for removing previous entries |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
27 static ref UNSET_RE: Regex = make_regex(r"^%unset\s+(\S+)"); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
28 /// A directive that allows for including other config files |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
29 static ref INCLUDE_RE: Regex = make_regex(r"^%include\s+(\S|\S.*\S)\s*$"); |
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 /// All config values separated by layers of precedence. |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
33 /// Each config source may be split in multiple layers if `%include` directives |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
34 /// are used. |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
35 /// TODO detail the general precedence |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
36 #[derive(Clone)] |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
37 pub struct ConfigLayer { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
38 /// Mapping of the sections to their items |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
39 sections: HashMap<Vec<u8>, ConfigItem>, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
40 /// All sections (and their items/values) in a layer share the same origin |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
41 pub origin: ConfigOrigin, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
42 /// Whether this layer comes from a trusted user or group |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
43 pub trusted: bool, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
44 } |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
45 |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
46 impl ConfigLayer { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
47 pub fn new(origin: ConfigOrigin) -> Self { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
48 ConfigLayer { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
49 sections: HashMap::new(), |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
50 trusted: true, // TODO check |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
51 origin, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
52 } |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
53 } |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
54 |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
55 /// Add an entry to the config, overwriting the old one if already present. |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
56 pub fn add( |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
57 &mut self, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
58 section: Vec<u8>, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
59 item: Vec<u8>, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
60 value: Vec<u8>, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
61 line: Option<usize>, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
62 ) { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
63 self.sections |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
64 .entry(section) |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
65 .or_insert_with(|| HashMap::new()) |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
66 .insert(item, ConfigValue { bytes: value, line }); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
67 } |
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 /// Returns the config value in `<section>.<item>` if it exists |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
70 pub fn get(&self, section: &[u8], item: &[u8]) -> Option<&ConfigValue> { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
71 Some(self.sections.get(section)?.get(item)?) |
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 pub fn is_empty(&self) -> bool { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
75 self.sections.is_empty() |
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 |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
78 /// Returns a `Vec` of layers in order of precedence (so, in read order), |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
79 /// recursively parsing the `%include` directives if any. |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
80 pub fn parse(src: &Path, data: &[u8]) -> Result<Vec<Self>, ConfigError> { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
81 let mut layers = vec![]; |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
82 |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
83 // Discard byte order mark if any |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
84 let data = if data.starts_with(b"\xef\xbb\xbf") { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
85 &data[3..] |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
86 } else { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
87 data |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
88 }; |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
89 |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
90 // TODO check if it's trusted |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
91 let mut current_layer = Self::new(ConfigOrigin::File(src.to_owned())); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
92 |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
93 let mut lines_iter = |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
94 data.split(|b| *b == b'\n').enumerate().peekable(); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
95 let mut section = b"".to_vec(); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
96 |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
97 while let Some((index, bytes)) = lines_iter.next() { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
98 if let Some(m) = INCLUDE_RE.captures(&bytes) { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
99 let filename_bytes = &m[1]; |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
100 let filename_to_include = get_path_from_bytes(&filename_bytes); |
46447
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
101 let (include_src, result) = |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
102 read_include(&src, &filename_to_include); |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
103 let data = result.for_file(filename_to_include)?; |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
104 layers.push(current_layer); |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
105 layers.extend(Self::parse(&include_src, &data)?); |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
106 current_layer = Self::new(ConfigOrigin::File(src.to_owned())); |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
107 } else if let Some(_) = EMPTY_RE.captures(&bytes) { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
108 } else if let Some(m) = SECTION_RE.captures(&bytes) { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
109 section = m[1].to_vec(); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
110 } else if let Some(m) = ITEM_RE.captures(&bytes) { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
111 let item = m[1].to_vec(); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
112 let mut value = m[2].to_vec(); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
113 loop { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
114 match lines_iter.peek() { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
115 None => break, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
116 Some((_, v)) => { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
117 if let Some(_) = COMMENT_RE.captures(&v) { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
118 } else if let Some(_) = CONT_RE.captures(&v) { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
119 value.extend(b"\n"); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
120 value.extend(&m[1]); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
121 } else { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
122 break; |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
123 } |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
124 } |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
125 }; |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
126 lines_iter.next(); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
127 } |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
128 current_layer.add( |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
129 section.clone(), |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
130 item, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
131 value, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
132 Some(index + 1), |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
133 ); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
134 } else if let Some(m) = UNSET_RE.captures(&bytes) { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
135 if let Some(map) = current_layer.sections.get_mut(§ion) { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
136 map.remove(&m[1]); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
137 } |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
138 } else { |
46447
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
139 return Err(ConfigParseError { |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
140 origin: ConfigOrigin::File(src.to_owned()), |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
141 line: Some(index + 1), |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
142 bytes: bytes.to_owned(), |
46447
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
143 } |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
144 .into()); |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
145 } |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
146 } |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
147 if !current_layer.is_empty() { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
148 layers.push(current_layer); |
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 Ok(layers) |
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 impl std::fmt::Debug for ConfigLayer { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
155 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
|
156 let mut sections: Vec<_> = self.sections.iter().collect(); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
157 sections.sort_by(|e0, e1| e0.0.cmp(e1.0)); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
158 |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
159 for (section, items) in sections.into_iter() { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
160 let mut items: Vec<_> = items.into_iter().collect(); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
161 items.sort_by(|e0, e1| e0.0.cmp(e1.0)); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
162 |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
163 for (item, config_entry) in items { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
164 writeln!( |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
165 f, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
166 "{}", |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
167 String::from_utf8_lossy(&format_bytes!( |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
168 b"{}.{}={} # {}", |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
169 section, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
170 item, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
171 &config_entry.bytes, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
172 &self.origin.to_bytes(), |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
173 )) |
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 } |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
176 } |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
177 Ok(()) |
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 } |
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 /// Mapping of section item to value. |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
182 /// In the following: |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
183 /// ```text |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
184 /// [ui] |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
185 /// paginate=no |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
186 /// ``` |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
187 /// "paginate" is the section item and "no" the value. |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
188 pub type ConfigItem = HashMap<Vec<u8>, ConfigValue>; |
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 #[derive(Clone, Debug, PartialEq)] |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
191 pub struct ConfigValue { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
192 /// The raw bytes of the value (be it from the CLI, env or from a file) |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
193 pub bytes: Vec<u8>, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
194 /// Only present if the value comes from a file, 1-indexed. |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
195 pub line: Option<usize>, |
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 |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
198 #[derive(Clone, Debug)] |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
199 pub enum ConfigOrigin { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
200 /// The value comes from a configuration file |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
201 File(PathBuf), |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
202 /// The value comes from the environment like `$PAGER` or `$EDITOR` |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
203 Environment(Vec<u8>), |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
204 /* TODO cli |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
205 * TODO defaults (configitems.py) |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
206 * TODO extensions |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
207 * TODO Python resources? |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
208 * Others? */ |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
209 } |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
210 |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
211 impl ConfigOrigin { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
212 /// TODO use some kind of dedicated trait? |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
213 pub fn to_bytes(&self) -> Vec<u8> { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
214 match self { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
215 ConfigOrigin::File(p) => get_bytes_from_path(p), |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
216 ConfigOrigin::Environment(e) => e.to_owned(), |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
217 } |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
218 } |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
219 } |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
220 |
46447
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
221 #[derive(Debug)] |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
222 pub struct ConfigParseError { |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
223 pub origin: ConfigOrigin, |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
224 pub line: Option<usize>, |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
225 pub bytes: Vec<u8>, |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
226 } |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
227 |
46435
2e2033081274
rust: replace trivial `impl From …` with `#[derive(derive_more::From)]`
Simon Sapin <simon.sapin@octobus.net>
parents:
46187
diff
changeset
|
228 #[derive(Debug, derive_more::From)] |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
229 pub enum ConfigError { |
46447
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
230 Parse(ConfigParseError), |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
231 Other(HgError), |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
232 } |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
233 |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
234 fn make_regex(pattern: &'static str) -> Regex { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
235 Regex::new(pattern).expect("expected a valid regex") |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
236 } |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
237 |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
238 /// Includes are relative to the file they're defined in, unless they're |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
239 /// absolute. |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
240 fn read_include( |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
241 old_src: &Path, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
242 new_src: &Path, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
243 ) -> (PathBuf, io::Result<Vec<u8>>) { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
244 if new_src.is_absolute() { |
46481
0d734c0ae1cf
rust: replace read_whole_file with std::fs::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46447
diff
changeset
|
245 (new_src.to_path_buf(), std::fs::read(&new_src)) |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
246 } else { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
247 let dir = old_src.parent().unwrap(); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
248 let new_src = dir.join(&new_src); |
46481
0d734c0ae1cf
rust: replace read_whole_file with std::fs::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46447
diff
changeset
|
249 (new_src.to_owned(), std::fs::read(&new_src)) |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
250 } |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
251 } |