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