nom_kconfig/attribute/
string.rs

1use nom::{
2    bytes::complete::tag,
3    combinator::map,
4    error::{Error, ErrorKind, ParseError},
5    sequence::delimited,
6    IResult, Input, Parser,
7};
8
9use crate::KconfigInput;
10
11pub fn parse_string(input: KconfigInput) -> IResult<KconfigInput, String> {
12    map(
13        delimited(tag("\""), take_until_unbalanced('"'), tag("\"")),
14        |d| d.fragment().to_string(),
15    )
16    .parse(input)
17}
18
19pub fn take_until_unbalanced(
20    delimiter: char,
21) -> impl Fn(KconfigInput) -> IResult<KconfigInput, KconfigInput> {
22    move |i: KconfigInput| {
23        let mut index: usize = 0;
24        let mut delimiter_counter = 0;
25
26        let end_of_line = match &i.find('\n') {
27            Some(e) => *e,
28            None => i.len(),
29        };
30
31        while let Some(n) = &i[index..end_of_line].find(delimiter) {
32            delimiter_counter += 1;
33            index += n + 1;
34        }
35
36        // we split just before the last double quote
37        index -= 1;
38        // Last delimiter is the string delimiter
39        delimiter_counter -= 1;
40
41        match delimiter_counter % 2 == 0 {
42            true => Ok(i.take_split(index)),
43            false => Err(nom::Err::Error(Error::from_error_kind(
44                i,
45                ErrorKind::TakeUntil,
46            ))),
47        }
48    }
49}