nom_kconfig/attribute/
range.rs1use nom::{
2 branch::alt,
3 bytes::complete::tag,
4 combinator::map,
5 sequence::{pair, preceded},
6 IResult, Parser,
7};
8#[cfg(feature = "deserialize")]
9use serde::Deserialize;
10#[cfg(feature = "serialize")]
11use serde::Serialize;
12#[cfg(feature = "display")]
13use std::fmt::Display;
14
15use crate::{
16 symbol::{parse_symbol, Symbol},
17 util::ws,
18 KconfigInput,
19};
20
21use super::expression::{parse_if_attribute, parse_number, Expression};
22
23#[derive(Debug, Clone, PartialEq)]
25#[cfg_attr(feature = "hash", derive(Hash))]
26#[cfg_attr(feature = "serialize", derive(Serialize))]
27#[cfg_attr(feature = "deserialize", derive(Deserialize))]
28pub struct Range {
29 pub lower_bound: Symbol,
30 pub upper_bound: Symbol,
31 #[cfg_attr(
32 any(feature = "serialize", feature = "deserialize"),
33 serde(skip_serializing_if = "Option::is_none")
34 )]
35 pub r#if: Option<Expression>,
36}
37
38#[cfg(feature = "display")]
39impl Display for Range {
40 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41 match &self.r#if {
42 Some(i) => write!(f, "{} {} if {}", self.lower_bound, self.upper_bound, i),
43 None => write!(f, "{} {}", self.lower_bound, self.upper_bound),
44 }
45 }
46}
47
48fn parse_bounds(input: KconfigInput) -> IResult<KconfigInput, (Symbol, Symbol)> {
49 alt((
50 map((ws(parse_number), ws(parse_number)), |(l, r)| {
51 (
52 Symbol::Constant(l.to_string()),
53 Symbol::Constant(r.to_string()),
54 )
55 }),
56 (ws(parse_symbol), ws(parse_symbol)),
57 ))
58 .parse(input)
59}
60
61pub fn parse_range(input: KconfigInput) -> IResult<KconfigInput, Range> {
84 map(
85 preceded(ws(tag("range")), pair(ws(parse_bounds), parse_if_attribute)),
86 |((l, r), i)| Range {
87 lower_bound: l,
88 upper_bound: r,
89 r#if: i,
90 },
91 )
92 .parse(input)
93}