nom_kconfig/attribute/expression/
mod.rs1pub mod atom;
2pub mod compare;
3#[cfg(test)]
4mod mod_test;
5pub mod term;
6
7pub use atom::*;
8pub use compare::*;
9pub use term::*;
10
11#[cfg(feature = "display")]
12use std::fmt::Display;
13
14use nom::{
15 bytes::complete::tag,
16 combinator::{map, opt},
17 multi::many0,
18 sequence::{pair, preceded},
19 IResult, Parser,
20};
21#[cfg(feature = "deserialize")]
22use serde::Deserialize;
23#[cfg(feature = "serialize")]
24use serde::Serialize;
25
26use crate::{util::wsi, KconfigInput};
27
28#[derive(Debug, PartialEq, Clone)]
29#[cfg_attr(feature = "serialize", derive(Serialize))]
30#[cfg_attr(feature = "deserialize", derive(Deserialize))]
31pub enum Operator {
32 And,
33 Or,
34}
35
36pub type Expression = OrExpression;
38#[cfg_attr(feature = "hash", derive(Hash))]
39#[cfg_attr(feature = "serialize", derive(Serialize))]
40#[cfg_attr(feature = "deserialize", derive(Deserialize))]
41#[derive(Debug, PartialEq, Clone)]
42pub enum AndExpression {
43 #[cfg_attr(feature = "serialize", serde(rename = "AndTerm"))]
44 Term(Term),
45 #[cfg_attr(feature = "serialize", serde(rename = "And"))]
46 Expression(Vec<Term>),
47}
48
49#[derive(Debug, PartialEq, Clone)]
50#[cfg_attr(feature = "hash", derive(Hash))]
51#[cfg_attr(feature = "serialize", derive(Serialize))]
52#[cfg_attr(feature = "deserialize", derive(Deserialize))]
53pub enum OrExpression {
54 #[cfg_attr(feature = "serialize", serde(rename = "OrTerm"))]
55 Term(AndExpression),
56 #[cfg_attr(feature = "serialize", serde(rename = "Or"))]
57 Expression(Vec<AndExpression>),
58}
59
60#[cfg(feature = "display")]
61impl Display for AndExpression {
62 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
63 match self {
64 Self::Term(t) => write!(f, "{}", t),
65 Self::Expression(t) => write!(
66 f,
67 "{}",
68 t.iter()
69 .map(|a| a.to_string())
70 .collect::<Vec<_>>()
71 .join(" && ")
72 ),
73 }
74 }
75}
76
77#[cfg(feature = "display")]
78impl Display for OrExpression {
79 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
80 match self {
81 Self::Term(t) => write!(f, "{}", t),
82 Self::Expression(t) => write!(
83 f,
84 "{}",
85 t.iter()
86 .map(|a| a.to_string())
87 .collect::<Vec<_>>()
88 .join(" || ")
89 ),
90 }
91 }
92}
93
94pub fn parse_or_expression(input: KconfigInput) -> IResult<KconfigInput, OrExpression> {
95 map(
96 (
97 wsi(parse_and_expression),
98 many0(preceded(wsi(tag("||")), wsi(parse_and_expression))),
99 ),
100 |(l, ee)| {
101 if ee.is_empty() {
102 OrExpression::Term(l)
103 } else {
104 let mut ll = vec![l];
105 ll.extend(ee);
106 OrExpression::Expression(ll)
107 }
108 },
109 )
110 .parse(input)
111}
112
113pub fn parse_and_expression(input: KconfigInput) -> IResult<KconfigInput, AndExpression> {
114 map(
115 (
116 wsi(parse_term),
117 many0(preceded(wsi(tag("&&")), wsi(parse_term))),
118 ),
119 |(l, ee)| {
120 if ee.is_empty() {
121 AndExpression::Term(l)
122 } else {
123 let mut ll = vec![l];
124 ll.extend(ee);
125 AndExpression::Expression(ll)
126 }
127 },
128 )
129 .parse(input)
130}
131
132pub fn parse_expression(input: KconfigInput) -> IResult<KconfigInput, Expression> {
133 parse_or_expression(input)
134}
135
136pub fn parse_if_attribute(input: KconfigInput) -> IResult<KconfigInput, Option<Expression>> {
137 opt(parse_if_expression).parse(input)
138}
139
140pub fn parse_if_expression(input: KconfigInput) -> IResult<KconfigInput, Expression> {
141 map(pair(wsi(tag("if")), wsi(parse_expression)), |(_, e)| e).parse(input)
142}