use nom::{branch::alt, bytes::complete::tag, combinator::map, sequence::tuple, IResult};
#[cfg(feature = "deserialize")]
use serde::Deserialize;
#[cfg(feature = "serialize")]
use serde::Serialize;
#[cfg(feature = "display")]
use std::fmt::Display;
use crate::{symbol::parse_constant_symbol, util::ws, KconfigInput};
use super::expression::{parse_if_attribute, Expression};
#[derive(Debug, Default, Clone, PartialEq)]
#[cfg_attr(feature = "hash", derive(Hash))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
pub struct Select {
pub symbol: String,
#[cfg_attr(
any(feature = "serialize", feature = "deserialize"),
serde(skip_serializing_if = "Option::is_none")
)]
pub r#if: Option<Expression>,
}
#[cfg(feature = "display")]
impl Display for Select {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self.r#if {
Some(i) => write!(f, "{} if {}", self.symbol, i),
None => write!(f, "{}", self.symbol),
}
}
}
pub fn parse_select(input: KconfigInput) -> IResult<KconfigInput, Select> {
map(
tuple((
ws(alt((tag("select"), tag("enable")))),
ws(parse_constant_symbol),
parse_if_attribute,
)),
|(_, s, i)| Select {
symbol: s.to_string(),
r#if: i,
},
)(input)
}