Skip to content

Commit 0084574

Browse files
committed
do not merge rules
1 parent 3f9264e commit 0084574

File tree

5 files changed

+129
-23
lines changed

5 files changed

+129
-23
lines changed

src/patch/device.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ impl DeviceExt for Device {
151151

152152
// Now process all peripherals
153153
for (periphspec, val) in device {
154-
let periphspec = periphspec.str()?;
154+
let periphspec = periphspec.key()?;
155155
if !periphspec.starts_with('_') {
156156
//val["_path"] = device["_path"]; // TODO: check
157157
self.process_peripheral(periphspec, val.hash()?, config)

src/patch/mod.rs

+32-5
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,11 @@ fn update_dict(parent: &mut Hash, child: &Hash) -> Result<()> {
194194
for (key, val) in child.iter() {
195195
match key {
196196
Yaml::String(key) if key == "_path" || key == "_include" => continue,
197-
key if parent.contains_key(key) => {
197+
Yaml::String(k) if parent.contains_key(key) && k.starts_with('_') => {
198198
if let Entry::Occupied(mut e) = parent.entry(key.clone()) {
199199
match e.get_mut() {
200200
el if el == val => {
201-
println!("In {key:?}: dublicate rule {val:?}, ignored");
201+
println!("In {k}: dublicate rule {val:?}, ignored");
202202
}
203203
Yaml::Array(a) => match val {
204204
Yaml::Array(val) => {
@@ -208,7 +208,7 @@ fn update_dict(parent: &mut Hash, child: &Hash) -> Result<()> {
208208
if !a.contains(val) {
209209
a.push(val.clone());
210210
} else {
211-
println!("In {key:?}: dublicate rule {val:?}, ignored");
211+
println!("In {k}: dublicate rule {val:?}, ignored");
212212
}
213213
}
214214
_ => {}
@@ -223,18 +223,45 @@ fn update_dict(parent: &mut Hash, child: &Hash) -> Result<()> {
223223
a.insert(0, s.clone());
224224
e.insert(Yaml::Array(a));
225225
} else {
226-
println!("In {key:?}: dublicate rule {s:?}, ignored");
226+
println!("In {k}: dublicate rule {s:?}, ignored");
227227
}
228228
}
229229
s2 if matches!(s2, Yaml::String(_)) => {
230-
println!("In {key:?}: conflicting rules {s:?} and {s2:?}, ignored");
230+
println!("In {k}: conflicting rules {s:?} and {s2:?}, ignored");
231231
}
232232
_ => {}
233233
},
234234
_ => {}
235235
}
236236
}
237237
}
238+
Yaml::String(_) if parent.contains_key(key) => {
239+
let mut i = 0;
240+
loop {
241+
let key = Yaml::Array(vec![key.clone(), Yaml::Integer(i)]);
242+
if !parent.contains_key(&key) {
243+
parent.insert(key, val.clone());
244+
break;
245+
}
246+
i += 1;
247+
}
248+
}
249+
Yaml::Array(a)
250+
if parent.contains_key(key)
251+
&& matches!(a.as_slice(), [Yaml::String(_), Yaml::Integer(_)]) =>
252+
{
253+
if let [k @ Yaml::String(_), Yaml::Integer(_)] = a.as_slice() {
254+
let mut i = 0;
255+
loop {
256+
let key = Yaml::Array(vec![k.clone(), Yaml::Integer(i)]);
257+
if !parent.contains_key(&key) {
258+
parent.insert(key, val.clone());
259+
break;
260+
}
261+
i += 1;
262+
}
263+
}
264+
}
238265
_ => {
239266
parent.insert(key.clone(), val.clone());
240267
}

src/patch/peripheral.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ impl PeripheralExt for Peripheral {
330330

331331
// Handle registers
332332
for (rspec, register) in pmod {
333-
let rspec = rspec.str()?;
333+
let rspec = rspec.key()?;
334334
if !rspec.starts_with('_') {
335335
self.process_register(rspec, register.hash()?, config)
336336
.with_context(|| format!("According to `{rspec}`"))?;
@@ -353,7 +353,7 @@ impl PeripheralExt for Peripheral {
353353

354354
// Handle clusters
355355
for (cspec, cluster) in pmod.hash_iter("_clusters") {
356-
let cspec = cspec.str()?;
356+
let cspec = cspec.key()?;
357357
if !cspec.starts_with('_') {
358358
self.process_cluster(cspec, cluster.hash()?, config)
359359
.with_context(|| format!("According to `{cspec}`"))?;
@@ -850,7 +850,7 @@ impl ClusterExt for Cluster {
850850

851851
// Handle clusters
852852
for (cspec, cluster) in pmod.hash_iter("_clusters") {
853-
let cspec = cspec.str()?;
853+
let cspec = cspec.key()?;
854854
if !cspec.starts_with('_') {
855855
self.process_cluster(cspec, cluster.hash()?, config)
856856
.with_context(|| format!("According to `{cspec}`"))?;
@@ -859,7 +859,7 @@ impl ClusterExt for Cluster {
859859

860860
// Handle registers
861861
for (rspec, register) in pmod {
862-
let rspec = rspec.str()?;
862+
let rspec = rspec.key()?;
863863
if !rspec.starts_with('_') {
864864
self.process_register(rspec, register.hash()?, config)
865865
.with_context(|| format!("According to `{rspec}`"))?;

src/patch/register.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ impl RegisterExt for Register {
182182
// Handle fields
183183
if config.update_fields {
184184
for (fspec, field) in rmod {
185-
let fspec = fspec.str()?;
185+
let fspec = fspec.key()?;
186186
if !fspec.starts_with('_') {
187187
self.process_field(pname, fspec, field, config)
188188
.with_context(|| format!("Processing field matched to `{fspec}`"))?;

src/patch/yaml_ext.rs

+91-12
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ pub enum YamlError {
1212
NotVec(Yaml),
1313
#[error("Value is not a string: {0:?}")]
1414
NotStr(Yaml),
15+
#[error("Value is not a supported hash key: {0:?}")]
16+
NotKey(Yaml),
1517
#[error("Value is not integer: {0:?}")]
1618
NotInt(Yaml),
1719
#[error("Value is not boolean: {0:?}")]
@@ -23,6 +25,7 @@ pub trait AsType {
2325
fn hash(&self) -> Result<&Hash, YamlError>;
2426
fn vec(&self) -> Result<&Vec<Yaml>, YamlError>;
2527
fn str(&self) -> Result<&str, YamlError>;
28+
fn key(&self) -> Result<&str, YamlError>;
2629
fn i64(&self) -> Result<i64, YamlError>;
2730
fn bool(&self) -> Result<bool, YamlError>;
2831
}
@@ -44,6 +47,19 @@ impl AsType for Yaml {
4447
fn str(&self) -> Result<&str, YamlError> {
4548
self.as_str().ok_or_else(|| YamlError::NotStr(self.clone()))
4649
}
50+
fn key(&self) -> Result<&str, YamlError> {
51+
match self {
52+
Yaml::String(k) => Ok(k),
53+
Yaml::Array(a) if matches!(a.as_slice(), [Yaml::String(_), Yaml::Integer(_)]) => {
54+
if let [Yaml::String(k), Yaml::Integer(_)] = a.as_slice() {
55+
Ok(k)
56+
} else {
57+
unreachable!()
58+
}
59+
}
60+
_ => Err(YamlError::NotKey(self.clone())),
61+
}
62+
}
4763
fn i64(&self) -> Result<i64, YamlError> {
4864
parse_i64(self).ok_or_else(|| YamlError::NotInt(self.clone()))
4965
}
@@ -148,26 +164,29 @@ impl<'a> Iterator for OverStringIter<'a> {
148164

149165
type HashIter<'a> = OptIter<linked_hash_map::Iter<'a, Yaml, Yaml>>;
150166

151-
pub trait GetVal {
152-
fn get_bool(&self, k: &str) -> Result<Option<bool>>;
153-
fn get_i64(&self, k: &str) -> Result<Option<i64>>;
154-
fn get_u64(&self, k: &str) -> Result<Option<u64>> {
167+
pub trait GetVal<K>
168+
where
169+
K: ?Sized,
170+
{
171+
fn get_bool(&self, k: &K) -> Result<Option<bool>>;
172+
fn get_i64(&self, k: &K) -> Result<Option<i64>>;
173+
fn get_u64(&self, k: &K) -> Result<Option<u64>> {
155174
self.get_i64(k).map(|v| v.map(|v| v as u64))
156175
}
157-
fn get_u32(&self, k: &str) -> Result<Option<u32>> {
176+
fn get_u32(&self, k: &K) -> Result<Option<u32>> {
158177
self.get_i64(k).map(|v| v.map(|v| v as u32))
159178
}
160-
fn get_str(&self, k: &str) -> Result<Option<&str>>;
161-
fn get_string(&self, k: &str) -> Result<Option<String>> {
179+
fn get_str(&self, k: &K) -> Result<Option<&str>>;
180+
fn get_string(&self, k: &K) -> Result<Option<String>> {
162181
self.get_str(k).map(|v| v.map(From::from))
163182
}
164-
fn get_hash(&self, k: &str) -> Result<Option<&Hash>>;
165-
fn hash_iter<'a>(&'a self, k: &str) -> HashIter<'a>;
166-
fn get_vec(&self, k: &str) -> Result<Option<&Vec<Yaml>>>;
167-
fn str_vec_iter<'a>(&'a self, k: &str) -> Result<OptIter<OverStringIter<'a>>>;
183+
fn get_hash(&self, k: &K) -> Result<Option<&Hash>>;
184+
fn hash_iter<'a>(&'a self, k: &K) -> HashIter<'a>;
185+
fn get_vec(&self, k: &K) -> Result<Option<&Vec<Yaml>>>;
186+
fn str_vec_iter<'a>(&'a self, k: &K) -> Result<OptIter<OverStringIter<'a>>>;
168187
}
169188

170-
impl GetVal for Hash {
189+
impl GetVal<str> for Hash {
171190
fn get_bool(&self, k: &str) -> Result<Option<bool>> {
172191
match self.get(&k.to_yaml()) {
173192
None => Ok(None),
@@ -230,3 +249,63 @@ impl GetVal for Hash {
230249
}))
231250
}
232251
}
252+
253+
impl GetVal<Yaml> for Hash {
254+
fn get_bool(&self, k: &Yaml) -> Result<Option<bool>> {
255+
match self.get(k) {
256+
None => Ok(None),
257+
Some(v) => v
258+
.bool()
259+
.with_context(|| format!("Under key `{k:?}`"))
260+
.map(Some),
261+
}
262+
}
263+
fn get_i64(&self, k: &Yaml) -> Result<Option<i64>> {
264+
match self.get(k) {
265+
None => Ok(None),
266+
Some(v) => v
267+
.i64()
268+
.with_context(|| format!("Under key `{k:?}`"))
269+
.map(Some),
270+
}
271+
}
272+
fn get_str(&self, k: &Yaml) -> Result<Option<&str>> {
273+
match self.get(k) {
274+
None => Ok(None),
275+
Some(v) => v
276+
.str()
277+
.with_context(|| format!("Under key `{k:?}`"))
278+
.map(Some),
279+
}
280+
}
281+
fn get_hash(&self, k: &Yaml) -> Result<Option<&Hash>> {
282+
match self.get(k) {
283+
None => Ok(None),
284+
Some(v) => v
285+
.hash()
286+
.with_context(|| format!("Under key `{k:?}`"))
287+
.map(Some),
288+
}
289+
}
290+
fn hash_iter<'a>(&'a self, k: &Yaml) -> HashIter<'a> {
291+
HashIter::new(self.get(k).and_then(Yaml::as_hash).map(|h| h.iter()))
292+
}
293+
fn get_vec(&self, k: &Yaml) -> Result<Option<&Vec<Yaml>>> {
294+
match self.get(k) {
295+
None => Ok(None),
296+
Some(v) => v
297+
.vec()
298+
.with_context(|| format!("Under key `{k:?}`"))
299+
.map(Some),
300+
}
301+
}
302+
fn str_vec_iter<'a>(&'a self, k: &Yaml) -> Result<OptIter<OverStringIter<'a>>> {
303+
Ok(OptIter::new(match self.get(k) {
304+
None => None,
305+
Some(y) if matches!(y, Yaml::String(_) | Yaml::Array(_)) => {
306+
Some(OverStringIter(y, None))
307+
}
308+
_ => return Err(anyhow!("`{k:?}` requires string value or array of strings")),
309+
}))
310+
}
311+
}

0 commit comments

Comments
 (0)