use std::time::{Duration, Instant};
fn numsub_count(v: &glide::Value, channel: &str) -> Option<i64> {
use glide::Value;
let is_chan = |k: &Value| match k {
Value::BulkString(b) => b.as_slice() == channel.as_bytes(),
Value::SimpleString(s) => s == channel,
_ => false,
};
match v {
Value::Array(items) => {
let mut it = items.iter();
while let (Some(k), Some(val)) = (it.next(), it.next()) {
if is_chan(k) {
return glide::value::to_i64(val.clone()).ok();
}
}
None
}
Value::Map(pairs) => pairs
.iter()
.find(|(k, _)| is_chan(k))
.and_then(|(_, val)| glide::value::to_i64(val.clone()).ok()),
_ => None,
}
}
pub async fn wait_for_numsub<C, F>(c: &C, channel: &str, mut pred: F, timeout: Duration) -> bool
where
C: glide::CustomCommand + Sync,
F: FnMut(i64) -> bool,
{
let deadline = Instant::now() + timeout;
loop {
if let Ok(v) = c.custom_command(&["PUBSUB", "NUMSUB", channel]).await
&& let Some(n) = numsub_count(&v, channel)
&& pred(n)
{
return true;
}
if Instant::now() >= deadline {
return false;
}
tokio::time::sleep(Duration::from_millis(50)).await;
}
}
pub async fn wait_for_numpat<C, F>(c: &C, mut pred: F, timeout: Duration) -> bool
where
C: glide::CustomCommand + Sync,
F: FnMut(i64) -> bool,
{
let deadline = Instant::now() + timeout;
loop {
if let Ok(v) = c.custom_command(&["PUBSUB", "NUMPAT"]).await
&& let Ok(n) = glide::value::to_i64(v)
&& pred(n)
{
return true;
}
if Instant::now() >= deadline {
return false;
}
tokio::time::sleep(Duration::from_millis(50)).await;
}
}