nom_kconfig/attribute/type/
mod.rs1use crate::Attribute;
2use crate::{util::ws, KconfigInput};
3use nom::sequence::pair;
4use nom::Parser;
5use nom::{
6 branch::alt,
7 bytes::complete::tag,
8 combinator::{map, opt},
9 sequence::preceded,
10 IResult,
11};
12#[cfg(feature = "deserialize")]
13use serde::Deserialize;
14#[cfg(feature = "serialize")]
15use serde::Serialize;
16#[cfg(feature = "display")]
17use std::fmt::Display;
18
19use super::{parse_expression, parse_if_attribute, parse_prompt_value, Expression};
20
21pub fn parse_type(input: KconfigInput) -> IResult<KconfigInput, Attribute> {
22 map(
23 pair(
24 ws(alt((
25 map(
26 preceded(tag("boolean"), opt(parse_prompt_value)),
27 Type::Bool,
28 ),
29 map(preceded(tag("bool"), opt(parse_prompt_value)), Type::Bool),
30 map(preceded(tag("hex"), opt(parse_prompt_value)), Type::Hex),
31 map(preceded(tag("int"), opt(parse_prompt_value)), Type::Int),
32 map(
33 preceded(tag("string"), opt(parse_prompt_value)),
34 Type::String,
35 ),
36 map(
37 preceded(tag("tristate"), opt(parse_prompt_value)),
38 Type::Tristate,
39 ),
40 map(preceded(tag("def_bool"), ws(parse_expression)), |e| {
41 Type::DefBool(e)
42 }),
43 map(preceded(tag("def_tristate"), ws(parse_expression)), |e| {
44 Type::DefTristate(e)
45 }),
46 #[cfg(feature = "kconfiglib")]
47 map(preceded(tag("def_int"), ws(parse_expression)), |e| {
48 Type::DefInt(e)
49 }),
50 #[cfg(feature = "kconfiglib")]
51 map(preceded(tag("def_hex"), ws(parse_expression)), |e| {
52 Type::DefHex(e)
53 }),
54 #[cfg(feature = "kconfiglib")]
55 map(preceded(tag("def_string"), ws(parse_expression)), |e| {
56 Type::DefString(e)
57 }),
58 ))),
59 parse_if_attribute,
60 ),
61 |(t, i)| Attribute::Type(ConfigType { r#type: t, r#if: i }),
62 )
63 .parse(input)
64}
65
66#[derive(Debug, PartialEq, Clone)]
67#[cfg_attr(feature = "hash", derive(Hash))]
68#[cfg_attr(feature = "serialize", derive(Serialize))]
69#[cfg_attr(feature = "deserialize", derive(Deserialize))]
70#[cfg_attr(
71 any(feature = "serialize", feature = "deserialize"),
72 serde(rename_all = "lowercase")
73)]
74pub enum Type {
75 Bool(Option<String>),
76 Tristate(Option<String>),
77 String(Option<String>),
78 Hex(Option<String>),
79 Int(Option<String>),
80 DefBool(Expression),
81 DefTristate(Expression),
82 #[cfg(feature = "kconfiglib")]
83 DefInt(Expression),
84 #[cfg(feature = "kconfiglib")]
85 DefHex(Expression),
86 #[cfg(feature = "kconfiglib")]
87 DefString(Expression),
88}
89
90#[derive(Debug, Clone, PartialEq)]
92#[cfg_attr(feature = "hash", derive(Hash))]
93#[cfg_attr(feature = "serialize", derive(Serialize))]
94#[cfg_attr(feature = "deserialize", derive(Deserialize))]
95pub struct ConfigType {
96 pub r#type: Type,
97 #[cfg_attr(
98 any(feature = "serialize", feature = "deserialize"),
99 serde(skip_serializing_if = "Option::is_none")
100 )]
101 pub r#if: Option<Expression>,
102}
103
104#[cfg(feature = "display")]
105impl Display for ConfigType {
106 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
107 match &self.r#if {
108 Some(i) => write!(f, "{} if {}", self.r#type, i),
109 None => write!(f, "{}", self.r#type),
110 }
111 }
112}
113
114#[cfg(feature = "display")]
115impl Display for Type {
116 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
117 match self {
118 Type::Bool(prompt) => fmt_type(f, "bool", prompt),
119 Type::Tristate(prompt) => fmt_type(f, "tristate", prompt),
120 Type::String(prompt) => fmt_type(f, "string", prompt),
121 Type::Hex(prompt) => fmt_type(f, "hex", prompt),
122 Type::Int(prompt) => fmt_type(f, "int", prompt),
123 Type::DefBool(v) => write!(f, "def_bool {}", v),
124 Type::DefTristate(v) => write!(f, "def_tristate {}", v),
125 #[cfg(feature = "kconfiglib")]
126 Type::DefInt(v) => write!(f, "def_int {}", v),
127 #[cfg(feature = "kconfiglib")]
128 Type::DefHex(v) => write!(f, "def_hex {}", v),
129 #[cfg(feature = "kconfiglib")]
130 Type::DefString(v) => write!(f, "def_string {}", v),
131 }
132 }
133}
134
135#[cfg(feature = "display")]
136fn fmt_type(
137 f: &mut std::fmt::Formatter,
138 keyword: &str,
139 prompt: &Option<String>,
140) -> std::fmt::Result {
141 match prompt {
142 Some(p) => write!(f, "{} \"{}\"", keyword, p),
143 None => write!(f, "{}", keyword),
144 }
145}
146
147#[cfg(test)]
148mod mod_test;