#[doc(hidden)]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
use crate::messages::{AboutEntity, PingEntity, ScoutingEntity};
use alloc::vec::Vec;
use alloc::{
borrow::ToOwned,
string::{String, ToString},
};
use chrono::Local;
use core::time::Duration;
use dimas_com::{traits::CommunicatorImplementationMethods, zenoh::Communicator};
use dimas_config::Config;
use dimas_core::{Result, enums::Signal, message_types::Message, utils::selector_from};
#[cfg(feature = "std")]
use std::collections::HashMap;
use zenoh::{
Wait,
config::{Locator, WhatAmI},
};
#[cfg(feature = "std")]
pub fn about_list(com: &Communicator, base_selector: &String) -> Result<Vec<AboutEntity>> {
let mut map: HashMap<String, AboutEntity> = HashMap::new();
let selector = selector_from("signal", Some(base_selector));
let message = Message::encode(&Signal::About);
com.get(
&selector,
Some(message),
Some(&mut |response| -> Result<()> {
let response: AboutEntity = response.decode()?;
map.entry(response.zid().to_string())
.or_insert(response);
Ok(())
}),
)?;
let result: Vec<AboutEntity> = map.values().cloned().collect();
Ok(result)
}
#[cfg(feature = "std")]
pub fn ping_list(com: &Communicator, base_selector: &String) -> Result<Vec<(PingEntity, i64)>> {
let mut map: HashMap<String, (PingEntity, i64)> = HashMap::new();
let selector = selector_from("signal", Some(base_selector));
let sent = Local::now()
.naive_utc()
.and_utc()
.timestamp_nanos_opt()
.unwrap_or(0);
let message = Message::encode(&Signal::Ping { sent });
com.get(
&selector,
Some(message),
Some(&mut |response| -> Result<()> {
let received = Local::now()
.naive_utc()
.and_utc()
.timestamp_nanos_opt()
.unwrap_or(0);
let response: PingEntity = response.decode()?;
let roundtrip = received - sent;
map.entry(response.zid().to_string())
.or_insert((response, roundtrip));
Ok(())
}),
)?;
let result: Vec<(PingEntity, i64)> = map.values().cloned().collect();
Ok(result)
}
#[cfg(feature = "std")]
pub fn scouting_list(config: &Config) -> Result<Vec<ScoutingEntity>> {
let mut map: HashMap<String, ScoutingEntity> = HashMap::new();
let what = WhatAmI::Router | WhatAmI::Peer | WhatAmI::Client;
let receiver = zenoh::scout(what, config.zenoh_config().to_owned()).wait()?;
while let Ok(Some(hello)) = receiver.recv_timeout(Duration::from_millis(250)) {
let zid = hello.zid().to_string();
let locators: Vec<String> = hello
.locators()
.iter()
.map(Locator::to_string)
.collect();
let entry = ScoutingEntity::new(zid.clone(), hello.whatami().to_string(), locators);
map.entry(zid).or_insert(entry);
}
let result: Vec<ScoutingEntity> = map.values().cloned().collect();
Ok(result)
}