1use std::collections::HashMap;
7
8use super::core::*;
9use super::error::*;
10use super::parser::*;
11use super::stmt::UnknownStmt;
12
13pub type StmtKeywordFn = fn() -> Keyword;
14pub type SelectionKeywordFn = fn() -> Vec<Keyword>;
15
16#[derive(Debug, Clone)]
17pub enum SubStmtWith {
18 Stmt(StmtKeywordFn),
19 Selection(SelectionKeywordFn),
20}
21
22#[derive(Debug, Clone)]
23pub enum SubStmtDef {
24 HasOne(SubStmtWith),
26 Optional(SubStmtWith),
28 ZeroOrMore(SubStmtWith),
30 OneOrMore(SubStmtWith),
32}
33
34#[derive(Debug, Clone)]
35pub struct RepeatCount {
36 pub count: usize,
37 pub min: usize,
38 pub max: usize,
39}
40
41pub struct SubStmtUtil;
45
46impl SubStmtUtil {
47 pub fn call_stmt_parser(parser: &mut Parser, keyword: &str) -> Result<YangStmt, YangError> {
49 let f = STMT_PARSER.get(keyword).unwrap();
50 f(parser)
51 }
52
53 pub fn parse_substmts(
54 parser: &mut Parser,
55 def: Vec<SubStmtDef>,
56 ) -> Result<StmtCollection, YangError> {
57 let mut k2i = HashMap::new();
60 let mut i2rep = HashMap::new();
62
63 let mut i = 0;
64 for s in def {
65 let (rep, ssw) = match s {
66 SubStmtDef::HasOne(ssw) => (
67 RepeatCount {
68 count: 0,
69 min: 1,
70 max: 1,
71 },
72 ssw,
73 ),
74 SubStmtDef::Optional(ssw) => (
75 RepeatCount {
76 count: 0,
77 min: 0,
78 max: 1,
79 },
80 ssw,
81 ),
82 SubStmtDef::ZeroOrMore(ssw) => (
83 RepeatCount {
84 count: 0,
85 min: 0,
86 max: usize::MAX,
87 },
88 ssw,
89 ),
90 SubStmtDef::OneOrMore(ssw) => (
91 RepeatCount {
92 count: 0,
93 min: 1,
94 max: usize::MAX,
95 },
96 ssw,
97 ),
98 };
99 i2rep.insert(i, rep);
100
101 match ssw {
102 SubStmtWith::Stmt(func) => {
103 k2i.insert(func(), i);
104 }
105 SubStmtWith::Selection(func) => {
106 for k in func() {
107 k2i.insert(k, i);
108 }
109 }
110 }
111
112 i += 1;
113 }
114
115 let mut stmts: StmtCollection = HashMap::new();
116
117 loop {
118 let token = parser.get_token()?;
119
120 if parser.config().debug() {
121 println!("*** [DEBUG] parse_substmts_default {:?}", token);
122 }
123 match token {
124 Token::Identifier(ref keyword) => {
125 if k2i.contains_key(keyword as &str) {
126 if let Some(rep) = i2rep.get_mut(k2i.get(keyword as &str).unwrap()) {
127 let stmt = Self::call_stmt_parser(parser, &keyword)?;
128 let v = match stmts.get_mut(keyword as &str) {
129 Some(v) => v,
130 None => {
131 stmts.insert(keyword.to_string(), Vec::new());
132 stmts.get_mut(keyword as &str).unwrap()
133 }
134 };
135 v.push(stmt);
136 rep.count += 1;
137 } else {
139 break;
140 }
141 } else if !STMT_PARSER.contains_key(keyword as &str) {
142 let _stmt = UnknownStmt::parse(parser, keyword)?;
144 } else {
146 parser.save_token(token);
147 break;
148 }
149 }
150 _ => {
151 parser.save_token(token);
152 break;
153 }
154 }
155 }
156
157 for k in stmts.keys() {
159 match k2i.get(k as &str) {
160 Some(i) => {
161 let rep = i2rep.get(i).unwrap();
162 if rep.count < rep.min {
163 return Err(YangError::TooFewStatement(k.clone()));
164 }
165 if rep.max < rep.count {
166 return Err(YangError::TooManyStatements(k.clone()));
167 }
168 }
169 None => return Err(YangError::UnexpectedStatement(k.clone())),
170 }
171 }
172
173 if parser.config().debug() {
174 println!("*** [DEBUG] end");
175 }
176
177 Ok(stmts)
178 }
179}