prns_config/reference/
parse.rs1use crate::configobj;
2use crate::diagnostic::{ConfigDiagnostic, ConfigDiagnosticCode, ConfigErrors, ConfigReport};
3
4use super::interpret::interpret;
5use super::types::ReferenceConfig;
6use super::validation::{legacy_diagnostic, validate, ValidationResult};
7
8pub fn parse(input: &str) -> Result<ReferenceConfig, ConfigErrors> {
9 parse_named("config", input).map(|report| report.value)
10}
11
12pub fn parse_named(
13 source: impl Into<String>,
14 input: &str,
15) -> Result<ConfigReport<ReferenceConfig>, ConfigErrors> {
16 let source = source.into();
17 let parsed = match configobj::parse_located(input) {
18 Ok(parsed) => parsed,
19 Err(error) => {
20 let line = error.line();
21 return Err(ConfigErrors::new(vec![ConfigDiagnostic::new(
22 ConfigDiagnosticCode::Syntax,
23 source,
24 line,
25 "<document>",
26 None,
27 error.to_string(),
28 Some(
29 "stock ConfigObj syntax with section headers and key = value entries"
30 .to_string(),
31 ),
32 format!("correct the syntax on line {line}"),
33 )]));
34 }
35 };
36 let warnings = match validate(&source, &parsed.root, &parsed.locations) {
37 ValidationResult::Valid { warnings } => warnings.into_inner(),
38 ValidationResult::Invalid { errors, warnings } => {
39 return Err(ConfigErrors::new((*errors).with_warnings(warnings)));
40 }
41 };
42 let value = interpret(&parsed.root).map_err(|error| {
43 ConfigErrors::new(vec![legacy_diagnostic(&source, &parsed.locations, error)])
44 })?;
45 Ok(ConfigReport {
46 value,
47 warnings,
48 source,
49 locations: parsed.locations,
50 })
51}