use nom::{branch::alt, bytes::complete::tag, combinator::map, sequence::tuple, IResult};
#[cfg(feature = "deserialize")]
use serde::Deserialize;
#[cfg(feature = "serialize")]
use serde::Serialize;
use crate::{
symbol::{parse_symbol, Symbol},
util::ws,
KconfigInput,
};
use super::expression::{parse_if_attribute, parse_number, Expression};
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "hash", derive(Hash))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
pub struct Range {
pub lhs: Symbol,
pub rhs: Symbol,
#[cfg_attr(
any(feature = "serialize", feature = "deserialize"),
serde(skip_serializing_if = "Option::is_none")
)]
pub r#if: Option<Expression>,
}
fn parse_hs(input: KconfigInput) -> IResult<KconfigInput, (Symbol, Symbol)> {
alt((
map(tuple((ws(parse_number), ws(parse_number))), |(l, r)| {
(
Symbol::Constant(l.to_string()),
Symbol::Constant(r.to_string()),
)
}),
tuple((ws(parse_symbol), ws(parse_symbol))),
))(input)
}
pub fn parse_range(input: KconfigInput) -> IResult<KconfigInput, Range> {
map(
tuple((ws(tag("range")), ws(parse_hs), parse_if_attribute)),
|(_, (l, r), i)| Range {
lhs: l,
rhs: r,
r#if: i,
},
)(input)
}