Skip to content

Commit d24e33b

Browse files
authored
internal Query::empty doesn't require self (#1783)
* internal Query::empty doesn't require self * Add dummy key expression methods for internal use * clippy fixes * no need to mark Sample::empty() unsafe anymore * Reply::empty() is safe, as well as Sample::empty()
1 parent 5250e2e commit d24e33b

File tree

7 files changed

+75
-7
lines changed

7 files changed

+75
-7
lines changed

zenoh/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ zenoh-codec = { workspace = true }
107107
zenoh-collections = { workspace = true, features = ["std"] }
108108
zenoh-config = { workspace = true }
109109
zenoh-core = { workspace = true }
110-
zenoh-keyexpr = { workspace = true }
110+
zenoh-keyexpr = { workspace = true, features = ["internal"] }
111111
zenoh-link = { workspace = true }
112112
zenoh-macros = { workspace = true }
113113
zenoh-plugin-trait = { workspace = true }

zenoh/src/api/key_expr.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ impl KeyExpr<'static> {
8989
)))
9090
}
9191
}
92+
93+
static KEYEXPR_DUMMY: &keyexpr = unsafe { keyexpr::from_str_unchecked("dummy") };
94+
9295
impl<'a> KeyExpr<'a> {
9396
/// Equivalent to `<KeyExpr as TryFrom>::try_from(t)`.
9497
///
@@ -103,6 +106,31 @@ impl<'a> KeyExpr<'a> {
103106
Self::try_from(t)
104107
}
105108

109+
/// Constructs key expression object to be used as dummy value
110+
/// for empty objects. This method is not supposed to be called in user code,
111+
/// but may be used in language bindings (zenoh-c)
112+
#[zenoh_macros::internal]
113+
pub fn dummy() -> Self {
114+
Self(KeyExprInner::Borrowed(KEYEXPR_DUMMY))
115+
}
116+
117+
#[cfg(not(feature = "internal"))]
118+
pub(crate) fn dummy() -> Self {
119+
Self(KeyExprInner::Borrowed(KEYEXPR_DUMMY))
120+
}
121+
122+
/// Checks if the key expression is the dummy one.
123+
/// This method is not supposed to be called in user code,
124+
/// but may be used in language bindings (zenoh-c)
125+
#[zenoh_macros::internal]
126+
pub fn is_dummy(&self) -> bool {
127+
let Self(inner) = self;
128+
let KeyExprInner::Borrowed(key_expr) = inner else {
129+
return false;
130+
};
131+
std::ptr::eq(*key_expr, KEYEXPR_DUMMY)
132+
}
133+
106134
/// Constructs a new [`KeyExpr`] aliasing `self`.
107135
///
108136
/// Note that [`KeyExpr`] (as well as [`OwnedKeyExpr`]) use reference counters internally, so you're probably better off using clone.

zenoh/src/api/query.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ impl Reply {
158158

159159
/// Constructs an uninitialized empty Reply.
160160
#[zenoh_macros::internal]
161-
pub unsafe fn empty() -> Self {
161+
pub fn empty() -> Self {
162162
Reply {
163163
result: Ok(Sample::empty()),
164164
#[cfg(feature = "unstable")]

zenoh/src/api/queryable.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ use {
3434

3535
#[zenoh_macros::unstable]
3636
use crate::api::selector::ZenohParameters;
37+
#[zenoh_macros::internal]
38+
use crate::net::primitives::DummyPrimitives;
3739
use crate::{
3840
api::{
3941
builders::reply::{ReplyBuilder, ReplyBuilderDelete, ReplyBuilderPut, ReplyErrBuilder},
@@ -57,6 +59,19 @@ pub(crate) struct QueryInner {
5759
pub(crate) primitives: Arc<dyn Primitives>,
5860
}
5961

62+
impl QueryInner {
63+
#[zenoh_macros::internal]
64+
fn empty() -> Self {
65+
QueryInner {
66+
key_expr: KeyExpr::dummy(),
67+
parameters: Parameters::empty(),
68+
qid: 0,
69+
zid: ZenohIdProto::default(),
70+
primitives: Arc::new(DummyPrimitives),
71+
}
72+
}
73+
}
74+
6075
impl Drop for QueryInner {
6176
fn drop(&mut self) {
6277
self.primitives.send_response_final(ResponseFinal {
@@ -202,9 +217,9 @@ impl Query {
202217

203218
/// Constructs an empty Query without payload, nor attachment referencing the same inner query.
204219
#[zenoh_macros::internal]
205-
pub unsafe fn empty(&self) -> Self {
220+
pub unsafe fn empty() -> Self {
206221
Query {
207-
inner: self.inner.clone(),
222+
inner: Arc::new(QueryInner::empty()),
208223
eid: 0,
209224
value: None,
210225
attachment: None,

zenoh/src/api/sample.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,9 +432,9 @@ impl Sample {
432432

433433
/// Constructs an uninitialized empty Sample.
434434
#[zenoh_macros::internal]
435-
pub unsafe fn empty() -> Self {
435+
pub fn empty() -> Self {
436436
Sample {
437-
key_expr: KeyExpr::from_str_unchecked(""),
437+
key_expr: KeyExpr::dummy(),
438438
payload: ZBytes::new(),
439439
kind: SampleKind::Put,
440440
encoding: Encoding::default(),

zenoh/src/api/session.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2113,7 +2113,7 @@ impl SessionInner {
21132113
drop(state);
21142114
let mut sample = info.clone().into_sample(
21152115
// SAFETY: the keyexpr is valid
2116-
unsafe { KeyExpr::from_str_unchecked("dummy") },
2116+
KeyExpr::dummy(),
21172117
payload,
21182118
#[cfg(feature = "unstable")]
21192119
reliability,

zenoh/tests/keyexpr.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//
2+
// Copyright (c) 2025 ZettaScale Technology
3+
//
4+
// This program and the accompanying materials are made available under the
5+
// terms of the Eclipse Public License 2.0 which is available at
6+
// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7+
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
8+
//
9+
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10+
//
11+
// Contributors:
12+
// ZettaScale Zenoh Team, <[email protected]>
13+
//
14+
#[cfg(feature = "internal")]
15+
use zenoh::key_expr::KeyExpr;
16+
17+
#[test]
18+
#[cfg(feature = "internal")]
19+
fn keyexpr_test_dummy() {
20+
let dummy_expr = KeyExpr::dummy();
21+
assert!(dummy_expr.is_dummy());
22+
23+
let non_dummy_expr = KeyExpr::try_from("dummy").unwrap();
24+
assert!(!non_dummy_expr.is_dummy());
25+
}

0 commit comments

Comments
 (0)