pub struct QueryCondition<'domain, 'participant, 'topic, 'reader, T, F>{ /* private fields */ }Expand description
A filter on a Reader that restricts samples by their
State and a predicate.
A QueryCondition extends ReadCondition with a
user-supplied predicate F that is applied to each sample’s payload. Only
samples that both match the state mask and satisfy the predicate are
returned by reads and trigger waitset wakeups.
§Predicate requirements
The predicate closure provided to the QueryCondition must be
zero-sized.
This restriction comes from how the callback is integrated with the underlying C API. For ergonomics, the closure is reconstructed inside a wrapper that converts raw C types into Rust types before invoking it. That reconstruction depends only on the closure’s type, so it cannot rely on any captured state.
In practice, this means the callback must be either:
- a function item, which is always zero-sized, or
- a closure that does not capture any variables from its environment
The following example will fail to compile because the closure captures
x, making it non-zero-sized:
use cyclonedds as dds;
use dds::state;
struct Data {
x: i32,
}
fn create_your_reader() -> dds::Reader<'static, 'static, 'static, Data> {
unimplemented!()
}
let reader: dds::Reader<Data> = create_your_reader();
let x = 10;
let result = dds::QueryCondition::new(
&reader,
state::sample::Any | state::instance::Any | state::view::Any,
// Error: closure captures `x`, so it is not zero-sized.
|sample| sample.x < x,
)?;Instead, use a function item or a non-capturing closure, for example:
|sample| sample.x < 10The compiler will emit an error similar to:
error[E0080]: evaluation panicked: the provided callback is not zero-sized
= note: closures that capture values from their environment are not zero-sized
= help: ensure the callback is either:
- a function item, e.g. `fn my_callback() {}`
- a closure that does not capture any external stateThis is enforced via an internal compile-time assertion
assert!(size_of::<F>() == 0) but note that the associated compiler output
can be quite lengthy.
Click to see a sample of the full compiler output
error[E0080]: evaluation panicked: the provided callback is not zero-sized
= note: closures that capture values from their environment are not zero-sized
= help: ensure the callback is either:
- a function item, e.g. `fn my_callback() {}`
- a closure that does not capture any external state
--> cyclonedds/src/internal/ffi.rs
|
| const IS_PROVIDED_CALLBACK_ZERO_SIZED: () = assert!(
| _________________________________________________^
| | size_of::<F>() == 0,
| | "\
| | the provided callback is not zero-sized
|
| | "
| | );
| |_^ evaluation of `<QueryCondition as Filter>::IS_PROVIDED_CALLBACK_ZERO_SIZED` failed here
note: erroneous constant encountered
--> cyclonedds/src/query_condition.rs:84:17
|
| Self::IS_PROVIDED_CALLBACK_ZERO_SIZED;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
note: erroneous constant encountered
--> cyclonedds/src/internal/ffi.rs
|
| Callback::IS_PROVIDED_CALLBACK_ZERO_SIZED;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^Implementations§
Source§impl<'d, 'p, 't, 'r, T, F> QueryCondition<'d, 'p, 't, 'r, T, F>
impl<'d, 'p, 't, 'r, T, F> QueryCondition<'d, 'p, 't, 'r, T, F>
Sourcepub fn new(reader: &'r Reader<'d, 'p, 't, T>, mask: State, _: F) -> Result<Self>
pub fn new(reader: &'r Reader<'d, 'p, 't, T>, mask: State, _: F) -> Result<Self>
Creates a new QueryCondition on reader that matches samples whose
state satisfies mask and whose payload satisfies the predicate F.
The predicate is passed by value but must be zero-sized. Non-capturing
closures and function pointers satisfy this requirement. The
UnwindSafe bound is required because the
predicate is called across the FFI boundary from within Cyclone DDS.
§Errors
Returns an Error if F is not zero-sized or if the
query condition fails to create.
§Examples
use cyclonedds::{QueryCondition, state};
let topic = Topic::<Data>::new(&participant, "MyTopic")?;
let reader = Reader::new(&topic)?;
let condition =
QueryCondition::new(&reader, state::sample::Fresh, |sample: &Data| sample.x > 10)?;Sourcepub fn mask(&self) -> Result<State>
pub fn mask(&self) -> Result<State>
Returns the state mask this condition was created with.
§Errors
Returns an Error if the mask returned by the query
condition is invalid.
§Examples
use cyclonedds::{QueryCondition, state};
let topic = Topic::<Data>::new(&participant, "MyTopic")?;
let reader = Reader::new(&topic)?;
let condition = QueryCondition::new(&reader, state::sample::Fresh, |_: &Data| true)?;
assert_eq!(condition.mask()?, state::sample::Fresh);Sourcepub fn triggered(&self) -> Result<bool>
pub fn triggered(&self) -> Result<bool>
Returns true if this condition is currently triggered.
A condition is triggered when samples matching its mask are available in the reader cache.
§Errors
returns an Error if the query condition fails to read
the trigger state.
§Examples
use cyclonedds::{QueryCondition, state};
let topic = Topic::<Data>::new(&participant, "MyTopic")?;
let reader = Reader::new(&topic)?;
let writer = Writer::new(&topic)?;
let condition = QueryCondition::new(
&reader,
state::sample::Fresh | state::view::Any | state::instance::Any,
|sample: &Data| sample.x == 4 && sample.y == 0,
)?;
writer.write(&Data { x: 4, y: 0 })?;
assert!(condition.triggered()?);Sourcepub fn take(&self) -> Result<Vec<SampleOrKey<T>>>where
T: Clone,
pub fn take(&self) -> Result<Vec<SampleOrKey<T>>>where
T: Clone,
Removes and returns all samples matching this condition’s mask and predicate from the reader cache.
§Errors
Returns an Error if the query condition fails to take
samples.
§Examples
use cyclonedds::{QueryCondition, state};
let topic = Topic::<Data>::new(&participant, "MyTopic")?;
let reader = Reader::new(&topic)?;
let writer = Writer::new(&topic)?;
let condition = QueryCondition::new(
&reader,
state::sample::Any | state::view::Any | state::instance::Any,
|sample: &Data| true,
)?;
writer.write(&Data { x: 1, y: 0 })?;
writer.write(&Data { x: 100, y: 0 })?;
// Attempt a normal read.
assert_eq!(reader.peek()?.len(), 2);
// Both samples should match.
let samples = condition.take()?;
assert_eq!(samples.len(), 2);
// Samples should be removed from the cache.
assert_eq!(condition.take()?.len(), 0);Sourcepub fn read(&self) -> Result<Vec<SampleOrKey<T>>>where
T: Clone,
pub fn read(&self) -> Result<Vec<SampleOrKey<T>>>where
T: Clone,
Returns all samples matching this condition’s mask and predicate without marking them as read or removing them from the cache.
§Errors
Returns an Error if the query condition fails to peek
samples.
§Examples
use cyclonedds::{QueryCondition, state};
let topic = Topic::<Data>::new(&participant, "MyTopic")?;
let reader = Reader::new(&topic)?;
let writer = Writer::new(&topic)?;
let condition = QueryCondition::new(
&reader,
state::sample::Any | state::view::Any | state::instance::Any,
|sample: &Data| true,
)?;
writer.write(&Data { x: 1, y: 0 })?;
writer.write(&Data { x: 100, y: 0 })?;
// Attempt a normal read.
assert_eq!(reader.read()?.len(), 2);
// Both samples should match.
let samples = condition.read()?;
assert_eq!(samples.len(), 2);
// Samples remain in the cache.
assert_eq!(condition.read()?.len(), 2);Sourcepub fn peek(&self) -> Result<Vec<SampleOrKey<T>>>where
T: Clone,
pub fn peek(&self) -> Result<Vec<SampleOrKey<T>>>where
T: Clone,
Returns all samples matching this condition’s mask and predicate without marking them as read or removing them from the cache.
§Errors
Returns an Error if the query condition fails to peek
samples.
§Examples
use cyclonedds::{QueryCondition, state};
let topic = Topic::<Data>::new(&participant, "MyTopic")?;
let reader = Reader::new(&topic)?;
let writer = Writer::new(&topic)?;
let condition = QueryCondition::new(
&reader,
state::sample::Any | state::view::Any | state::instance::Any,
|sample: &Data| true,
)?;
writer.write(&Data { x: 1, y: 0 })?;
writer.write(&Data { x: 100, y: 0 })?;
// Attempt a normal peek.
assert_eq!(reader.peek()?.len(), 2);
// Both samples should match.
let samples = condition.peek()?;
assert_eq!(samples.len(), 2);
// Samples remain in the cache.
assert_eq!(condition.peek()?.len(), 2);Trait Implementations§
Source§impl<T, F> Debug for QueryCondition<'_, '_, '_, '_, T, F>
impl<T, F> Debug for QueryCondition<'_, '_, '_, '_, T, F>
Source§impl<T, F> Drop for QueryCondition<'_, '_, '_, '_, T, F>
impl<T, F> Drop for QueryCondition<'_, '_, '_, '_, T, F>
Source§impl<T: Topicable, F: Fn(&T) -> bool> Entity for QueryCondition<'_, '_, '_, '_, T, F>
impl<T: Topicable, F: Fn(&T) -> bool> Entity for QueryCondition<'_, '_, '_, '_, T, F>
Source§fn instance_handle(&self) -> Result<InstanceHandle>
fn instance_handle(&self) -> Result<InstanceHandle>
InstanceHandle of this entity. Read more