section_config.rs: simplify parser by using new try_block macro

This commit is contained in:
Dietmar Maurer 2019-02-15 12:13:15 +01:00
parent fe651dd6e5
commit 9b50c16103
2 changed files with 71 additions and 77 deletions

View File

@ -37,18 +37,12 @@ const DATASTORE_CFG_FILENAME: &str = "/etc/proxmox-backup/datastore.cfg";
pub fn config() -> Result<SectionConfigData, Error> { pub fn config() -> Result<SectionConfigData, Error> {
let mut file = match OpenOptions::new()
.create(true)
.read(true)
.write(true)
.open(DATASTORE_CFG_FILENAME) {
Ok(file) => file,
Err(err) => bail!("Unable to open '{}' - {}",
DATASTORE_CFG_FILENAME, err),
};
let mut contents = String::new(); let mut contents = String::new();
file.read_to_string(&mut contents)?;
try_block!({
let mut file = std::fs::File::open(DATASTORE_CFG_FILENAME)?;
file.read_to_string(&mut contents)
}).map_err(|e| format_err!("unable to read '{}' - {}", DATASTORE_CFG_FILENAME, e))?;
CONFIG.parse(DATASTORE_CFG_FILENAME, &contents) CONFIG.parse(DATASTORE_CFG_FILENAME, &contents)
} }

View File

@ -145,8 +145,6 @@ impl SectionConfig {
pub fn parse(&self, filename: &str, raw: &str) -> Result<SectionConfigData, Error> { pub fn parse(&self, filename: &str, raw: &str) -> Result<SectionConfigData, Error> {
let mut line_no = 0;
let mut state = ParseState::BeforeHeader; let mut state = ParseState::BeforeHeader;
let test_required_properties = |value: &Value, schema: &ObjectSchema| -> Result<(), Error> { let test_required_properties = |value: &Value, schema: &ObjectSchema| -> Result<(), Error> {
@ -158,6 +156,10 @@ impl SectionConfig {
Ok(()) Ok(())
}; };
let mut line_no = 0;
try_block!({
let mut result = SectionConfigData::new(); let mut result = SectionConfigData::new();
let mut create_section = |section_id: &str, type_name: &str, config| { let mut create_section = |section_id: &str, type_name: &str, config| {
@ -165,6 +167,7 @@ impl SectionConfig {
result.record_order(section_id); result.record_order(section_id);
}; };
try_block!({
for line in raw.lines() { for line in raw.lines() {
line_no += 1; line_no += 1;
@ -178,25 +181,21 @@ impl SectionConfig {
//println!("OKLINE: type: {} ID: {}", section_type, section_id); //println!("OKLINE: type: {} ID: {}", section_type, section_id);
if let Some(ref plugin) = self.plugins.get(&section_type) { if let Some(ref plugin) = self.plugins.get(&section_type) {
if let Err(err) = parse_simple_value(&section_id, &self.id_schema) { if let Err(err) = parse_simple_value(&section_id, &self.id_schema) {
bail!("file '{}' line {} - syntax error in section identifier: {}", bail!("syntax error in section identifier: {}", err.to_string());
filename, line_no, err.to_string());
} }
state = ParseState::InsideSection(plugin, section_id, json!({})); state = ParseState::InsideSection(plugin, section_id, json!({}));
} else { } else {
bail!("file '{}' line {} - unknown section type '{}'", bail!("unknown section type '{}'", section_type);
filename, line_no, section_type);
} }
} else { } else {
bail!("file '{}' line {} - syntax error (expected header)", filename, line_no); bail!("syntax error (expected header)");
} }
} }
ParseState::InsideSection(plugin, ref mut section_id, ref mut config) => { ParseState::InsideSection(plugin, ref mut section_id, ref mut config) => {
if line.trim().is_empty() { if line.trim().is_empty() {
// finish section // finish section
if let Err(err) = test_required_properties(config, &plugin.properties) { test_required_properties(config, &plugin.properties)?;
bail!("file '{}' line {} - {}", filename, line_no, err.to_string());
}
create_section(section_id, &plugin.type_name, config.take()); create_section(section_id, &plugin.type_name, config.take());
state = ParseState::BeforeHeader; state = ParseState::BeforeHeader;
continue; continue;
@ -210,20 +209,18 @@ impl SectionConfig {
if config[&key] == Value::Null { if config[&key] == Value::Null {
config[key] = value; config[key] = value;
} else { } else {
bail!("file '{}' line {} - duplicate property '{}'", bail!("duplicate property '{}'", key);
filename, line_no, key);
} }
} }
Err(err) => { Err(err) => {
bail!("file '{}' line {} - property '{}': {}", bail!("property '{}': {}", key, err.to_string());
filename, line_no, key, err.to_string());
} }
} }
} else { } else {
bail!("file '{}' line {} - unknown property '{}'", filename, line_no, key) bail!("unknown property '{}'", key)
} }
} else { } else {
bail!("file '{}' line {} - syntax error (expected section properties)", filename, line_no); bail!("syntax error (expected section properties)");
} }
} }
} }
@ -231,14 +228,17 @@ impl SectionConfig {
if let ParseState::InsideSection(plugin, section_id, config) = state { if let ParseState::InsideSection(plugin, section_id, config) = state {
// finish section // finish section
test_required_properties(&config, &plugin.properties)?;
if let Err(err) = test_required_properties(&config, &plugin.properties) {
bail!("file '{}' line {} - {}", filename, line_no, err.to_string());
}
create_section(&section_id, &plugin.type_name, config); create_section(&section_id, &plugin.type_name, config);
} }
Ok(())
}).map_err(|e| format_err!("line {} - {}", line_no, e))?;
Ok(result) Ok(result)
}).map_err(|e: Error| format_err!("parsing '{}' failed: {}", filename, e))
} }
pub fn default_format_section_header(type_name: &str, section_id: &str, _data: &Value) -> String { pub fn default_format_section_header(type_name: &str, section_id: &str, _data: &Value) -> String {