use serde::{Deserialize, Serialize};
use crate::protocol::JsonMessage;
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "op", rename = "connectionGraphUpdate", rename_all = "camelCase")]
pub struct ConnectionGraphUpdate {
pub published_topics: Vec<PublishedTopic>,
pub subscribed_topics: Vec<SubscribedTopic>,
pub advertised_services: Vec<AdvertisedService>,
pub removed_topics: Vec<String>,
pub removed_services: Vec<String>,
}
impl JsonMessage for ConnectionGraphUpdate {}
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PublishedTopic {
pub name: String,
pub publisher_ids: Vec<String>,
}
impl PublishedTopic {
pub fn new(
name: impl Into<String>,
publisher_ids: impl IntoIterator<Item = impl Into<String>>,
) -> Self {
Self {
name: name.into(),
publisher_ids: publisher_ids.into_iter().map(|id| id.into()).collect(),
}
}
}
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SubscribedTopic {
pub name: String,
pub subscriber_ids: Vec<String>,
}
impl SubscribedTopic {
pub fn new(
name: impl Into<String>,
subscriber_ids: impl IntoIterator<Item = impl Into<String>>,
) -> Self {
Self {
name: name.into(),
subscriber_ids: subscriber_ids.into_iter().map(|id| id.into()).collect(),
}
}
}
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AdvertisedService {
pub name: String,
pub provider_ids: Vec<String>,
}
impl AdvertisedService {
pub fn new(
name: impl Into<String>,
provider_ids: impl IntoIterator<Item = impl Into<String>>,
) -> Self {
Self {
name: name.into(),
provider_ids: provider_ids.into_iter().map(|id| id.into()).collect(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn message() -> ConnectionGraphUpdate {
ConnectionGraphUpdate {
published_topics: vec![PublishedTopic::new("/t1", ["p1", "p2"])],
subscribed_topics: vec![SubscribedTopic::new("/t2", ["s1", "s2"])],
advertised_services: vec![AdvertisedService::new("/s1", ["pr1", "pr2"])],
removed_topics: ["/t3", "/t4"].into_iter().map(String::from).collect(),
removed_services: ["/s2", "/s3"].into_iter().map(String::from).collect(),
}
}
#[test]
fn test_encode() {
insta::assert_json_snapshot!(message());
}
#[test]
fn test_roundtrip() {
let orig = message();
let buf = orig.to_string();
let parsed: ConnectionGraphUpdate = serde_json::from_str(&buf).unwrap();
assert_eq!(parsed, orig);
}
}