nom_config_in/entry/
source.rs

1use std::path::PathBuf;
2
3use nom::{
4    branch::alt,
5    bytes::complete::tag,
6    character::complete::{alphanumeric1, one_of},
7    combinator::{cut, map, recognize},
8    error::{Error, ErrorKind, ParseError},
9    multi::many1,
10    IResult,
11};
12
13use crate::{
14    config_in::ConfigIn,
15    parse_config_in,
16    util::{ws, wsi},
17    ConfigInFile, ConfigInInput,
18};
19
20/// Entry that reads the specified configuration file. This file is always parsed.
21pub type Source = ConfigIn;
22
23pub fn parse_source(input: ConfigInInput) -> IResult<ConfigInInput, Source> {
24    let (input, _) = ws(tag("source"))(input)?;
25    let (input, file) = wsi(parse_filepath)(input)?;
26    let source_kconfig_file = ConfigInFile::new(input.clone().extra.root_dir, PathBuf::from(file));
27    let source_content = source_kconfig_file
28        .read_to_string()
29        .map_err(|_| nom::Err::Error(Error::from_error_kind(input.clone(), ErrorKind::Fail)))?;
30
31    let binding = source_content.clone();
32    #[allow(clippy::let_and_return)]
33    let x = match cut(parse_config_in)(ConfigInInput::new_extra(
34        &binding,
35        source_kconfig_file.clone(),
36    )) {
37        Ok((_, kconfig)) => Ok((input, kconfig)),
38        Err(_e) => Err(nom::Err::Error(nom::error::Error::new(
39            ConfigInInput::new_extra("", source_kconfig_file),
40            ErrorKind::Fail,
41        ))),
42    };
43    x
44}
45pub fn parse_filepath(input: ConfigInInput) -> IResult<ConfigInInput, &str> {
46    map(
47        recognize(ws(many1(alt((alphanumeric1, recognize(one_of("_-/."))))))),
48        |c: ConfigInInput| c.trim(),
49    )(input)
50}