section_config.rs: simplify parser by using new try_block macro
This commit is contained in:
parent
fe651dd6e5
commit
9b50c16103
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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,87 +156,89 @@ impl SectionConfig {
|
|||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut result = SectionConfigData::new();
|
let mut line_no = 0;
|
||||||
|
|
||||||
let mut create_section = |section_id: &str, type_name: &str, config| {
|
try_block!({
|
||||||
result.set_data(section_id, type_name, config);
|
|
||||||
result.record_order(section_id);
|
|
||||||
};
|
|
||||||
|
|
||||||
for line in raw.lines() {
|
let mut result = SectionConfigData::new();
|
||||||
line_no += 1;
|
|
||||||
|
|
||||||
match state {
|
let mut create_section = |section_id: &str, type_name: &str, config| {
|
||||||
|
result.set_data(section_id, type_name, config);
|
||||||
|
result.record_order(section_id);
|
||||||
|
};
|
||||||
|
|
||||||
ParseState::BeforeHeader => {
|
try_block!({
|
||||||
|
for line in raw.lines() {
|
||||||
|
line_no += 1;
|
||||||
|
|
||||||
if line.trim().is_empty() { continue; }
|
match state {
|
||||||
|
|
||||||
if let Some((section_type, section_id)) = (self.parse_section_header)(line) {
|
ParseState::BeforeHeader => {
|
||||||
//println!("OKLINE: type: {} ID: {}", section_type, section_id);
|
|
||||||
if let Some(ref plugin) = self.plugins.get(§ion_type) {
|
|
||||||
if let Err(err) = parse_simple_value(§ion_id, &self.id_schema) {
|
|
||||||
bail!("file '{}' line {} - syntax error in section identifier: {}",
|
|
||||||
filename, line_no, err.to_string());
|
|
||||||
}
|
|
||||||
state = ParseState::InsideSection(plugin, section_id, json!({}));
|
|
||||||
} else {
|
|
||||||
bail!("file '{}' line {} - unknown section type '{}'",
|
|
||||||
filename, line_no, section_type);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bail!("file '{}' line {} - syntax error (expected header)", filename, line_no);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ParseState::InsideSection(plugin, ref mut section_id, ref mut config) => {
|
|
||||||
|
|
||||||
if line.trim().is_empty() {
|
if line.trim().is_empty() { continue; }
|
||||||
// finish section
|
|
||||||
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.take());
|
|
||||||
state = ParseState::BeforeHeader;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if let Some((key, value)) = (self.parse_section_content)(line) {
|
|
||||||
//println!("CONTENT: key: {} value: {}", key, value);
|
|
||||||
|
|
||||||
if let Some((_optional, prop_schema)) = plugin.properties.properties.get::<str>(&key) {
|
if let Some((section_type, section_id)) = (self.parse_section_header)(line) {
|
||||||
match parse_simple_value(&value, prop_schema) {
|
//println!("OKLINE: type: {} ID: {}", section_type, section_id);
|
||||||
Ok(value) => {
|
if let Some(ref plugin) = self.plugins.get(§ion_type) {
|
||||||
if config[&key] == Value::Null {
|
if let Err(err) = parse_simple_value(§ion_id, &self.id_schema) {
|
||||||
config[key] = value;
|
bail!("syntax error in section identifier: {}", err.to_string());
|
||||||
} else {
|
|
||||||
bail!("file '{}' line {} - duplicate property '{}'",
|
|
||||||
filename, line_no, key);
|
|
||||||
}
|
}
|
||||||
|
state = ParseState::InsideSection(plugin, section_id, json!({}));
|
||||||
|
} else {
|
||||||
|
bail!("unknown section type '{}'", section_type);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
} else {
|
||||||
bail!("file '{}' line {} - property '{}': {}",
|
bail!("syntax error (expected header)");
|
||||||
filename, line_no, key, err.to_string());
|
}
|
||||||
}
|
}
|
||||||
|
ParseState::InsideSection(plugin, ref mut section_id, ref mut config) => {
|
||||||
|
|
||||||
|
if line.trim().is_empty() {
|
||||||
|
// finish section
|
||||||
|
test_required_properties(config, &plugin.properties)?;
|
||||||
|
create_section(section_id, &plugin.type_name, config.take());
|
||||||
|
state = ParseState::BeforeHeader;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if let Some((key, value)) = (self.parse_section_content)(line) {
|
||||||
|
//println!("CONTENT: key: {} value: {}", key, value);
|
||||||
|
|
||||||
|
if let Some((_optional, prop_schema)) = plugin.properties.properties.get::<str>(&key) {
|
||||||
|
match parse_simple_value(&value, prop_schema) {
|
||||||
|
Ok(value) => {
|
||||||
|
if config[&key] == Value::Null {
|
||||||
|
config[key] = value;
|
||||||
|
} else {
|
||||||
|
bail!("duplicate property '{}'", key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
bail!("property '{}': {}", key, err.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bail!("unknown property '{}'", key)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bail!("syntax error (expected section properties)");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
bail!("file '{}' line {} - unknown property '{}'", filename, line_no, key)
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
bail!("file '{}' line {} - syntax error (expected section properties)", filename, line_no);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)?;
|
||||||
|
create_section(§ion_id, &plugin.type_name, config);
|
||||||
|
}
|
||||||
|
|
||||||
if let Err(err) = test_required_properties(&config, &plugin.properties) {
|
Ok(())
|
||||||
bail!("file '{}' line {} - {}", filename, line_no, err.to_string());
|
|
||||||
}
|
|
||||||
create_section(§ion_id, &plugin.type_name, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(result)
|
}).map_err(|e| format_err!("line {} - {}", line_no, e))?;
|
||||||
|
|
||||||
|
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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user