Skip to content

Commit

Permalink
Fix formatter reuse and fix issue with ** sometimes being considered …
Browse files Browse the repository at this point in the history
…as included into * (#638)

Co-authored-by: Pierre Avital <[email protected]>
  • Loading branch information
p-avital and Pierre Avital authored Jan 5, 2024
1 parent 5197fff commit a5d19a4
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 11 deletions.
24 changes: 14 additions & 10 deletions commons/zenoh-keyexpr/src/key_expr/format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,32 +387,36 @@ impl<'s, Storage: IKeFormatStorage<'s>> KeFormatter<'s, Storage> {
let Some(i) = segments.iter().position(|s| s.spec.id() == id) else {
return Err(FormatSetError::InvalidId);
};
if let Some((start, end)) = self.values.as_ref()[i] {
let values = self.values.as_mut();
if let Some((start, end)) = values[i].take() {
let end = end.get();
let shift = end - start;
self.buffer.replace_range(start as usize..end as usize, "");
for (start, end) in self.values.as_mut()[(i + 1)..].iter_mut().flatten() {
*start -= shift;
*end = NonZeroU32::new(end.get() - shift).unwrap()
for (s, e) in values.iter_mut().flatten() {
if *s < start {
continue;
}
*s -= shift;
*e = NonZeroU32::new(e.get() - shift).unwrap()
}
}
let pattern = segments[i].spec.pattern();
let start = self.buffer.len();
write!(&mut self.buffer, "{value}").unwrap(); // Writing on `&mut String` should be infallible.
match (|| {
let end = self.buffer.len();
if !(end == start && pattern.as_str() == "**") {
if pattern.as_str() != "**" {
let Ok(ke) = keyexpr::new(&self.buffer[start..end]) else {
return Err(());
};
if end > u32::MAX as usize || !pattern.includes(ke) {
if !pattern.includes(ke) {
return Err(());
}
}
self.values.as_mut()[i] = Some((start as u32, unsafe {
// `end` must be >0 for self.buffer[start..end] to be a keyexpr
NonZeroU32::new_unchecked(end as u32)
}));
values[i] = Some((
start as u32,
NonZeroU32::new(end.try_into().map_err(|_| ())?).ok_or(())?,
));
Ok(())
})() {
Ok(()) => Ok(self),
Expand Down
5 changes: 4 additions & 1 deletion commons/zenoh-keyexpr/src/key_expr/include.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ impl Includer<&[u8], &[u8]> for LTRIncluder {
}
} else {
let (rchunk, rrest) = right.split_once(&DELIMITER);
if rchunk.is_empty() || !self.non_double_wild_chunk_includes(lchunk, rchunk) {
if rchunk.is_empty()
|| rchunk == DOUBLE_WILD
|| !self.non_double_wild_chunk_includes(lchunk, rchunk)
{
return false;
}
let rempty = rrest.is_empty();
Expand Down
23 changes: 23 additions & 0 deletions zenoh/tests/formatters.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#[test]
fn reuse() {
zenoh::kedefine!(
pub gkeys: "zenoh/${group:*}/${member:*}",
);
let mut formatter = gkeys::formatter();
let k1 = zenoh::keformat!(formatter, group = "foo", member = "bar").unwrap();
assert_eq!(dbg!(k1).as_str(), "zenoh/foo/bar");

formatter.set("member", "*").unwrap();
let k2 = formatter.build().unwrap();
assert_eq!(dbg!(k2).as_str(), "zenoh/foo/*");

dbg!(&mut formatter).group("foo").unwrap();
dbg!(&mut formatter).member("*").unwrap();
let k2 = dbg!(&mut formatter).build().unwrap();
assert_eq!(dbg!(k2).as_str(), "zenoh/foo/*");

let k3 = zenoh::keformat!(formatter, group = "foo", member = "*").unwrap();
assert_eq!(dbg!(k3).as_str(), "zenoh/foo/*");

zenoh::keformat!(formatter, group = "**", member = "**").unwrap_err();
}

0 comments on commit a5d19a4

Please sign in to comment.