1use nom::{
2 branch::alt,
3 bytes::complete::take_until,
4 character::complete::{alphanumeric1, char, one_of},
5 combinator::{map, recognize},
6 multi::many1,
7 sequence::delimited,
8 IResult, Parser,
9};
10#[cfg(feature = "deserialize")]
11use serde::Deserialize;
12#[cfg(feature = "serialize")]
13use serde::Serialize;
14
15use crate::KconfigInput;
16
17use super::util::ws;
18
19#[derive(Debug, PartialEq, Clone)]
25#[cfg_attr(feature = "hash", derive(Hash))]
26#[cfg_attr(feature = "serialize", derive(Serialize))]
27#[cfg_attr(feature = "deserialize", derive(Deserialize))]
28pub enum Symbol {
29 Constant(String),
30 NonConstant(String),
31}
32
33pub fn parse_symbol(input: KconfigInput) -> IResult<KconfigInput, Symbol> {
34 alt((
35 map(parse_constant_symbol, |c: &str| {
36 Symbol::Constant(c.to_string())
37 }),
38 map(
39 delimited(ws(char('"')), take_until("\""), char('"')),
40 |c: KconfigInput| Symbol::NonConstant(format!("\"{}\"", c)),
41 ),
42 map(
43 delimited(ws(char('\'')), take_until("'"), char('\'')),
44 |c: KconfigInput| Symbol::NonConstant(format!("'{}'", c)),
45 ),
46 ))
47 .parse(input)
48}
49
50pub fn parse_constant_symbol(input: KconfigInput<'_>) -> IResult<KconfigInput<'_>, &str> {
51 map(
52 recognize(ws(many1(alt((alphanumeric1, recognize(one_of("._"))))))),
53 |c: KconfigInput| c.trim(),
54 )
55 .parse(input)
56}
57
58#[cfg(feature = "display")]
59use std::fmt::Display;
60#[cfg(feature = "display")]
61impl Display for Symbol {
62 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
63 match self {
64 Symbol::Constant(c) => write!(f, "{}", c),
65 Symbol::NonConstant(c) => write!(f, "\"{}\"", c),
66 }
67 }
68}