tether_utils/
tether_send.rs

1use clap::Args;
2use log::{debug, error, info, warn};
3use serde::Serialize;
4use tether_agent::{ChannelDef, ChannelDefBuilder, ChannelSenderDefBuilder, TetherAgent};
5
6#[derive(Args)]
7pub struct SendOptions {
8    /// Overide the auto-generated topic with your own, to use with every published message
9    #[arg(long = "channel.name")]
10    pub channel_name: Option<String>,
11
12    /// Overide Tether Agent role with your own, to use with every published message
13    #[arg(long = "channel.role")]
14    pub channel_role: Option<String>,
15
16    /// Overide Tether Agent ID with your own, to use with every published message
17    #[arg(long = "channel.id")]
18    pub channel_id: Option<String>,
19
20    /// Overide the entire topic string (ignoring any defaults or customisations applied elsewhere),
21    /// to use with every published message
22    #[arg(long = "topic")]
23    pub channel_topic: Option<String>,
24
25    /// Provide a custom message as an escaped JSON string which will be converted
26    /// into MessagePack; by default the payload will be empty.
27    #[arg(long = "message")]
28    pub message_payload_json: Option<String>,
29
30    /// Flag to generate dummy data for the MessagePack payload; useful for testing.
31    /// Any custom message will be ignored if enabled.
32    #[arg(long = "dummyData")]
33    pub use_dummy_data: bool,
34}
35
36#[derive(Serialize, Debug)]
37struct DummyData {
38    id: usize,
39    a_float: f32,
40    an_int_array: Vec<usize>,
41    a_string: String,
42}
43
44pub fn send(options: &SendOptions, tether_agent: &mut TetherAgent) -> anyhow::Result<()> {
45    info!("Tether Send Utility");
46
47    let channel_name = options
48        .channel_name
49        .clone()
50        .unwrap_or("testMessages".into());
51
52    let channel_def = ChannelSenderDefBuilder::new(&channel_name)
53        .role(options.channel_role.as_deref())
54        .id(options.channel_id.as_deref())
55        .override_topic(options.channel_topic.as_deref())
56        .build(tether_agent);
57
58    let channel = tether_agent.create_sender_with_def(channel_def.clone());
59
60    info!(
61        "Sending on topic \"{}\" ...",
62        channel.definition().generated_topic()
63    );
64
65    if options.use_dummy_data {
66        let payload = DummyData {
67            id: 0,
68            a_float: 42.0,
69            an_int_array: vec![1, 2, 3, 4],
70            a_string: "hello world".into(),
71        };
72        info!("Sending dummy data {:?}", payload);
73        return match tether_agent.send(&channel, &payload) {
74            Ok(_) => {
75                info!("Sent dummy data message OK");
76                Ok(())
77            }
78            Err(e) => Err(e),
79        };
80    }
81
82    match &options.message_payload_json {
83        Some(custom_message) => {
84            debug!(
85                "Attempting to decode provided custom message-as-string \"{}\"",
86                &custom_message
87            );
88            match serde_json::from_str::<serde_json::Value>(custom_message) {
89                Ok(json) => {
90                    let msgpack_payload =
91                        rmp_serde::to_vec_named(&json).expect("failed to convert JSON to MsgPack");
92                    tether_agent
93                        .send_raw(&channel_def, Some(&msgpack_payload))
94                        .expect("failed to publish");
95                    // encoded.
96                    // channel.send_raw(&encoded).expect("failed to publish");
97                    // tether_agent
98                    //     .send(&channel, &encoded)
99                    //     .expect("failed to publish");
100                    info!("Sent message OK");
101                    Ok(())
102                }
103                Err(e) => {
104                    error!("Could not serialise String -> JSON; error: {}", e);
105                    Err(e.into())
106                }
107            }
108        }
109        None => {
110            warn!("Sending empty message");
111            match tether_agent.send_empty(&channel_def) {
112                Ok(_) => {
113                    info!("Sent empty message OK");
114                    Ok(())
115                }
116                Err(e) => {
117                    error!("Failed to send empty message: {}", e);
118                    Err(e)
119                }
120            }
121        }
122    }
123}