tether_agent::agent

Struct TetherAgentOptionsBuilder

Source
pub struct TetherAgentOptionsBuilder { /* private fields */ }

Implementations§

Source§

impl TetherAgentOptionsBuilder

Source

pub fn new(role: &str) -> Self

Initialise Tether Options struct with default options; call other methods to customise. Call build() to get the actual TetherAgent instance (and connect automatically, by default)

Examples found in repository?
examples/custom_options.rs (line 8)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
fn main() {
    let mut tether_agent = TetherAgentOptionsBuilder::new("example")
        .id(None)
        .host(Some("localhost"))
        .port(Some(1883))
        .username(Some("tether"))
        .password(Some("sp_ceB0ss!"))
        .build()
        .expect("failed to create Tether Agent");

    let output_plug = PlugOptionsBuilder::create_output("anOutput")
        .role(Some("pretendingToBeSomethingElse"))
        .qos(Some(2))
        .retain(Some(true))
        .build(&mut tether_agent)
        .expect("failed to create output plug");
    let input_wildcard_plug = PlugOptionsBuilder::create_input("everything")
        .topic(Some("#"))
        .build(&mut tether_agent);

    let input_customid_plug = PlugOptionsBuilder::create_input("someData")
        .role(None) // i.e., just use default
        .id(Some("specificIDonly"))
        .build(&mut tether_agent);

    println!("Agent looks like this: {:?}", tether_agent.description());
    let (role, id, _) = tether_agent.description();
    assert_eq!(role, "example");
    assert_eq!(id, "any"); // because we set None

    if let PlugDefinition::OutputPlug(p) = &output_plug {
        println!("output plug: {:?}", p);
        assert_eq!(p.topic_str(), "pretendingToBeSomethingElse/any/anOutput");
    }

    println!("wildcard input plug: {:?}", input_wildcard_plug);
    println!("speific ID input plug: {:?}", input_customid_plug);

    let payload =
        rmp_serde::to_vec::<String>(&String::from("boo")).expect("failed to serialise payload");
    tether_agent
        .publish(&output_plug, Some(&payload))
        .expect("failed to publish");

    std::thread::sleep(Duration::from_millis(4000));
}
More examples
Hide additional examples
examples/publish.rs (line 22)
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
fn main() {
    println!("Rust Tether Agent publish example");

    let mut builder = Builder::from_env(Env::default().default_filter_or("info"));
    builder.init();

    debug!("Debugging is enabled; could be verbose");

    let mut tether_agent = TetherAgentOptionsBuilder::new("RustDemo")
        .build()
        .expect("failed to connect Tether");
    let (role, id, _) = tether_agent.description();
    info!("Created agent OK: {}, {}", role, id);

    let empty_message_output = PlugOptionsBuilder::create_output("nothing")
        .build(&mut tether_agent)
        .expect("failed to create output");
    let boolean_message_output = PlugOptionsBuilder::create_output("one")
        .build(&mut tether_agent)
        .expect("failed to create output");
    let custom_output = PlugOptionsBuilder::create_output("two")
        .topic(Some("custom/custom/two"))
        .build(&mut tether_agent)
        .expect("failed to create output");
    let grouped_output_1 = PlugOptionsBuilder::create_output("one")
        .id(Some("groupMessages"))
        .build(&mut tether_agent)
        .expect("failed to create output");
    let grouped_output_2 = PlugOptionsBuilder::create_output("two")
        .id(Some("groupMessages"))
        .build(&mut tether_agent)
        .expect("failed to create output");

    for i in 1..=10 {
        info!("#{i}: Sending empty message...");
        tether_agent.publish(&empty_message_output, None).unwrap();

        let bool = i % 2 == 0;
        info!("#{i}: Sending boolean message...");
        tether_agent
            .publish(&boolean_message_output, Some(&[bool.into()]))
            .unwrap();

        info!("#{i}: Sending custom struct message...");
        let custom_message = CustomStruct {
            id: i,
            name: "hello".into(),
        };
        tether_agent
            .encode_and_publish(&custom_output, custom_message)
            .unwrap();

        info!("#{i}: Sending grouped messages...");
        tether_agent.publish(&grouped_output_1, None).unwrap();
        tether_agent.publish(&grouped_output_2, None).unwrap();

        thread::sleep(Duration::from_millis(1000))
    }
}
examples/subscribe.rs (line 27)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
fn main() {
    println!("Rust Tether Agent subscribe example");

    let mut builder = Builder::from_env(Env::default().default_filter_or("debug"));
    builder.filter_module("tether_agent", log::LevelFilter::Warn);
    builder.filter_module("rumqttc", log::LevelFilter::Warn);
    builder.init();

    debug!("Debugging is enabled; could be verbose");

    let mut tether_agent = TetherAgentOptionsBuilder::new("RustDemo")
        .id(Some("example"))
        .build()
        .expect("failed to init Tether agent");

    let input_one = PlugOptionsBuilder::create_input("one")
        .build(&mut tether_agent)
        .expect("failed to create input");
    info!("input one {} = {}", input_one.name(), input_one.topic());
    let input_two = PlugOptionsBuilder::create_input("two")
        .role(Some("specific"))
        .build(&mut tether_agent)
        .expect("failed to create input");
    info!("input two {} = {}", input_two.name(), input_two.topic());
    let input_empty = PlugOptionsBuilder::create_input("nothing")
        .build(&mut tether_agent)
        .expect("failed to create input");

    let input_everything = PlugOptionsBuilder::create_input("everything")
        .topic(Some("#"))
        .build(&mut tether_agent)
        .expect("failed to create input");

    let input_specify_id = PlugOptionsBuilder::create_input("groupMessages")
        .id(Some("someGroup"))
        .name(None)
        .build(&mut tether_agent)
        .expect("failed to create input");

    debug!(
        "input everything {} = {}",
        input_everything.name(),
        input_everything.topic()
    );

    info!("Checking messages every 1s, 10x...");

    loop {
        debug!("Checking for messages...");
        while let Some((topic, payload)) = tether_agent.check_messages() {
            // debug!(
            //     "........ Received a message topic {:?} => topic parts {:?}",
            //     topic, topic
            // );

            if input_one.matches(&topic) {
                info!(
                            "******** INPUT ONE:\n Received a message for plug named \"{}\" on topic {:?} with length {} bytes",
                            input_one.name(),
                            topic,
                            payload.len()
                        );
                // assert_eq!(parse_plug_name(topic.un), Some("one"));
            }
            if input_two.matches(&topic) {
                info!(
                        "******** INPUT TWO:\n Received a message for plug named \"{}\" on topic {:?} with length {} bytes",
                        input_two.name(),
                        topic,
                        payload.len()
                    );
                // assert_eq!(parse_plug_name(message.topic()), Some("two"));
                // assert_ne!(parse_plug_name(message.topic()), Some("one"));

                // Notice how you must give the from_slice function a type so it knows what to expect
                let decoded = from_slice::<CustomMessage>(&payload);
                match decoded {
                    Ok(d) => {
                        info!("Yes, we decoded the MessagePack payload as: {:?}", d);
                        let CustomMessage { name, id } = d;
                        debug!("Name is {} and ID is {}", name, id);
                    }
                    Err(e) => {
                        warn!("Failed to decode the payload: {}", e)
                    }
                };
            }
            if input_empty.matches(&topic) {
                info!(
                        "******** EMPTY MESSAGE:\n Received a message for plug named \"{}\" on topic {:?} with length {} bytes",
                        input_empty.name(),
                        topic,
                       payload.len()
                    );
                // assert_eq!(parse_plug_name(topic), Some("nothing"));
            }
            if input_everything.matches(&topic) {
                info!(
                    "******** EVERYTHING MATCHES HERE:\n Received a message for plug named \"{}\" on topic {:?} with length {} bytes",
                    input_everything.name(),
                    topic,
                   payload.len()
                );
            }
            if input_specify_id.matches(&topic) {
                info!("******** ID MATCH:\n Should match any role and plug name, but only messages with ID \"groupMessages\"");
                info!(
                    "\n Received a message from plug named \"{}\" on topic {:?} with length {} bytes",
                    input_specify_id.name(),
                    topic,
                    payload.len()
                );
                // assert_eq!(parse_agent_id(message.topic()), Some("groupMessages"));
            }
        }

        thread::sleep(Duration::from_millis(1000))
    }
}
Source

pub fn id(self, id: Option<&str>) -> Self

Optionally sets the Tether ID, as used in auto-generating topics such as myRole/myID/myPlug not the MQTT Client ID. Provide Some(value) to override or None to use the default any (when publishing) or + when subscribing.

Examples found in repository?
examples/custom_options.rs (line 9)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
fn main() {
    let mut tether_agent = TetherAgentOptionsBuilder::new("example")
        .id(None)
        .host(Some("localhost"))
        .port(Some(1883))
        .username(Some("tether"))
        .password(Some("sp_ceB0ss!"))
        .build()
        .expect("failed to create Tether Agent");

    let output_plug = PlugOptionsBuilder::create_output("anOutput")
        .role(Some("pretendingToBeSomethingElse"))
        .qos(Some(2))
        .retain(Some(true))
        .build(&mut tether_agent)
        .expect("failed to create output plug");
    let input_wildcard_plug = PlugOptionsBuilder::create_input("everything")
        .topic(Some("#"))
        .build(&mut tether_agent);

    let input_customid_plug = PlugOptionsBuilder::create_input("someData")
        .role(None) // i.e., just use default
        .id(Some("specificIDonly"))
        .build(&mut tether_agent);

    println!("Agent looks like this: {:?}", tether_agent.description());
    let (role, id, _) = tether_agent.description();
    assert_eq!(role, "example");
    assert_eq!(id, "any"); // because we set None

    if let PlugDefinition::OutputPlug(p) = &output_plug {
        println!("output plug: {:?}", p);
        assert_eq!(p.topic_str(), "pretendingToBeSomethingElse/any/anOutput");
    }

    println!("wildcard input plug: {:?}", input_wildcard_plug);
    println!("speific ID input plug: {:?}", input_customid_plug);

    let payload =
        rmp_serde::to_vec::<String>(&String::from("boo")).expect("failed to serialise payload");
    tether_agent
        .publish(&output_plug, Some(&payload))
        .expect("failed to publish");

    std::thread::sleep(Duration::from_millis(4000));
}
More examples
Hide additional examples
examples/subscribe.rs (line 28)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
fn main() {
    println!("Rust Tether Agent subscribe example");

    let mut builder = Builder::from_env(Env::default().default_filter_or("debug"));
    builder.filter_module("tether_agent", log::LevelFilter::Warn);
    builder.filter_module("rumqttc", log::LevelFilter::Warn);
    builder.init();

    debug!("Debugging is enabled; could be verbose");

    let mut tether_agent = TetherAgentOptionsBuilder::new("RustDemo")
        .id(Some("example"))
        .build()
        .expect("failed to init Tether agent");

    let input_one = PlugOptionsBuilder::create_input("one")
        .build(&mut tether_agent)
        .expect("failed to create input");
    info!("input one {} = {}", input_one.name(), input_one.topic());
    let input_two = PlugOptionsBuilder::create_input("two")
        .role(Some("specific"))
        .build(&mut tether_agent)
        .expect("failed to create input");
    info!("input two {} = {}", input_two.name(), input_two.topic());
    let input_empty = PlugOptionsBuilder::create_input("nothing")
        .build(&mut tether_agent)
        .expect("failed to create input");

    let input_everything = PlugOptionsBuilder::create_input("everything")
        .topic(Some("#"))
        .build(&mut tether_agent)
        .expect("failed to create input");

    let input_specify_id = PlugOptionsBuilder::create_input("groupMessages")
        .id(Some("someGroup"))
        .name(None)
        .build(&mut tether_agent)
        .expect("failed to create input");

    debug!(
        "input everything {} = {}",
        input_everything.name(),
        input_everything.topic()
    );

    info!("Checking messages every 1s, 10x...");

    loop {
        debug!("Checking for messages...");
        while let Some((topic, payload)) = tether_agent.check_messages() {
            // debug!(
            //     "........ Received a message topic {:?} => topic parts {:?}",
            //     topic, topic
            // );

            if input_one.matches(&topic) {
                info!(
                            "******** INPUT ONE:\n Received a message for plug named \"{}\" on topic {:?} with length {} bytes",
                            input_one.name(),
                            topic,
                            payload.len()
                        );
                // assert_eq!(parse_plug_name(topic.un), Some("one"));
            }
            if input_two.matches(&topic) {
                info!(
                        "******** INPUT TWO:\n Received a message for plug named \"{}\" on topic {:?} with length {} bytes",
                        input_two.name(),
                        topic,
                        payload.len()
                    );
                // assert_eq!(parse_plug_name(message.topic()), Some("two"));
                // assert_ne!(parse_plug_name(message.topic()), Some("one"));

                // Notice how you must give the from_slice function a type so it knows what to expect
                let decoded = from_slice::<CustomMessage>(&payload);
                match decoded {
                    Ok(d) => {
                        info!("Yes, we decoded the MessagePack payload as: {:?}", d);
                        let CustomMessage { name, id } = d;
                        debug!("Name is {} and ID is {}", name, id);
                    }
                    Err(e) => {
                        warn!("Failed to decode the payload: {}", e)
                    }
                };
            }
            if input_empty.matches(&topic) {
                info!(
                        "******** EMPTY MESSAGE:\n Received a message for plug named \"{}\" on topic {:?} with length {} bytes",
                        input_empty.name(),
                        topic,
                       payload.len()
                    );
                // assert_eq!(parse_plug_name(topic), Some("nothing"));
            }
            if input_everything.matches(&topic) {
                info!(
                    "******** EVERYTHING MATCHES HERE:\n Received a message for plug named \"{}\" on topic {:?} with length {} bytes",
                    input_everything.name(),
                    topic,
                   payload.len()
                );
            }
            if input_specify_id.matches(&topic) {
                info!("******** ID MATCH:\n Should match any role and plug name, but only messages with ID \"groupMessages\"");
                info!(
                    "\n Received a message from plug named \"{}\" on topic {:?} with length {} bytes",
                    input_specify_id.name(),
                    topic,
                    payload.len()
                );
                // assert_eq!(parse_agent_id(message.topic()), Some("groupMessages"));
            }
        }

        thread::sleep(Duration::from_millis(1000))
    }
}
Source

pub fn protocol(self, protocol: Option<&str>) -> Self

Provide Some(value) to override or None to use default

Source

pub fn mqtt_client_id(self, client_id: Option<&str>) -> Self

Optionally set the MQTT Client ID used when connecting to the MQTT broker. This is not the same as the Tether ID used for auto-generating topics.

By default we use a UUID for this value, in order to avoid hard-to-debug issues where Tether Agent instances share the same Client ID and therefore events/messages are not handled properly by all instances.

Source

pub fn host(self, host: Option<&str>) -> Self

Provide Some(value) to override or None to use default

Examples found in repository?
examples/custom_options.rs (line 10)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
fn main() {
    let mut tether_agent = TetherAgentOptionsBuilder::new("example")
        .id(None)
        .host(Some("localhost"))
        .port(Some(1883))
        .username(Some("tether"))
        .password(Some("sp_ceB0ss!"))
        .build()
        .expect("failed to create Tether Agent");

    let output_plug = PlugOptionsBuilder::create_output("anOutput")
        .role(Some("pretendingToBeSomethingElse"))
        .qos(Some(2))
        .retain(Some(true))
        .build(&mut tether_agent)
        .expect("failed to create output plug");
    let input_wildcard_plug = PlugOptionsBuilder::create_input("everything")
        .topic(Some("#"))
        .build(&mut tether_agent);

    let input_customid_plug = PlugOptionsBuilder::create_input("someData")
        .role(None) // i.e., just use default
        .id(Some("specificIDonly"))
        .build(&mut tether_agent);

    println!("Agent looks like this: {:?}", tether_agent.description());
    let (role, id, _) = tether_agent.description();
    assert_eq!(role, "example");
    assert_eq!(id, "any"); // because we set None

    if let PlugDefinition::OutputPlug(p) = &output_plug {
        println!("output plug: {:?}", p);
        assert_eq!(p.topic_str(), "pretendingToBeSomethingElse/any/anOutput");
    }

    println!("wildcard input plug: {:?}", input_wildcard_plug);
    println!("speific ID input plug: {:?}", input_customid_plug);

    let payload =
        rmp_serde::to_vec::<String>(&String::from("boo")).expect("failed to serialise payload");
    tether_agent
        .publish(&output_plug, Some(&payload))
        .expect("failed to publish");

    std::thread::sleep(Duration::from_millis(4000));
}
Source

pub fn port(self, port: Option<u16>) -> Self

Examples found in repository?
examples/custom_options.rs (line 11)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
fn main() {
    let mut tether_agent = TetherAgentOptionsBuilder::new("example")
        .id(None)
        .host(Some("localhost"))
        .port(Some(1883))
        .username(Some("tether"))
        .password(Some("sp_ceB0ss!"))
        .build()
        .expect("failed to create Tether Agent");

    let output_plug = PlugOptionsBuilder::create_output("anOutput")
        .role(Some("pretendingToBeSomethingElse"))
        .qos(Some(2))
        .retain(Some(true))
        .build(&mut tether_agent)
        .expect("failed to create output plug");
    let input_wildcard_plug = PlugOptionsBuilder::create_input("everything")
        .topic(Some("#"))
        .build(&mut tether_agent);

    let input_customid_plug = PlugOptionsBuilder::create_input("someData")
        .role(None) // i.e., just use default
        .id(Some("specificIDonly"))
        .build(&mut tether_agent);

    println!("Agent looks like this: {:?}", tether_agent.description());
    let (role, id, _) = tether_agent.description();
    assert_eq!(role, "example");
    assert_eq!(id, "any"); // because we set None

    if let PlugDefinition::OutputPlug(p) = &output_plug {
        println!("output plug: {:?}", p);
        assert_eq!(p.topic_str(), "pretendingToBeSomethingElse/any/anOutput");
    }

    println!("wildcard input plug: {:?}", input_wildcard_plug);
    println!("speific ID input plug: {:?}", input_customid_plug);

    let payload =
        rmp_serde::to_vec::<String>(&String::from("boo")).expect("failed to serialise payload");
    tether_agent
        .publish(&output_plug, Some(&payload))
        .expect("failed to publish");

    std::thread::sleep(Duration::from_millis(4000));
}
Source

pub fn username(self, username: Option<&str>) -> Self

Provide Some(value) to override or None to use default

Examples found in repository?
examples/custom_options.rs (line 12)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
fn main() {
    let mut tether_agent = TetherAgentOptionsBuilder::new("example")
        .id(None)
        .host(Some("localhost"))
        .port(Some(1883))
        .username(Some("tether"))
        .password(Some("sp_ceB0ss!"))
        .build()
        .expect("failed to create Tether Agent");

    let output_plug = PlugOptionsBuilder::create_output("anOutput")
        .role(Some("pretendingToBeSomethingElse"))
        .qos(Some(2))
        .retain(Some(true))
        .build(&mut tether_agent)
        .expect("failed to create output plug");
    let input_wildcard_plug = PlugOptionsBuilder::create_input("everything")
        .topic(Some("#"))
        .build(&mut tether_agent);

    let input_customid_plug = PlugOptionsBuilder::create_input("someData")
        .role(None) // i.e., just use default
        .id(Some("specificIDonly"))
        .build(&mut tether_agent);

    println!("Agent looks like this: {:?}", tether_agent.description());
    let (role, id, _) = tether_agent.description();
    assert_eq!(role, "example");
    assert_eq!(id, "any"); // because we set None

    if let PlugDefinition::OutputPlug(p) = &output_plug {
        println!("output plug: {:?}", p);
        assert_eq!(p.topic_str(), "pretendingToBeSomethingElse/any/anOutput");
    }

    println!("wildcard input plug: {:?}", input_wildcard_plug);
    println!("speific ID input plug: {:?}", input_customid_plug);

    let payload =
        rmp_serde::to_vec::<String>(&String::from("boo")).expect("failed to serialise payload");
    tether_agent
        .publish(&output_plug, Some(&payload))
        .expect("failed to publish");

    std::thread::sleep(Duration::from_millis(4000));
}
Source

pub fn password(self, password: Option<&str>) -> Self

Provide Some(value) to override or None to use default

Examples found in repository?
examples/custom_options.rs (line 13)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
fn main() {
    let mut tether_agent = TetherAgentOptionsBuilder::new("example")
        .id(None)
        .host(Some("localhost"))
        .port(Some(1883))
        .username(Some("tether"))
        .password(Some("sp_ceB0ss!"))
        .build()
        .expect("failed to create Tether Agent");

    let output_plug = PlugOptionsBuilder::create_output("anOutput")
        .role(Some("pretendingToBeSomethingElse"))
        .qos(Some(2))
        .retain(Some(true))
        .build(&mut tether_agent)
        .expect("failed to create output plug");
    let input_wildcard_plug = PlugOptionsBuilder::create_input("everything")
        .topic(Some("#"))
        .build(&mut tether_agent);

    let input_customid_plug = PlugOptionsBuilder::create_input("someData")
        .role(None) // i.e., just use default
        .id(Some("specificIDonly"))
        .build(&mut tether_agent);

    println!("Agent looks like this: {:?}", tether_agent.description());
    let (role, id, _) = tether_agent.description();
    assert_eq!(role, "example");
    assert_eq!(id, "any"); // because we set None

    if let PlugDefinition::OutputPlug(p) = &output_plug {
        println!("output plug: {:?}", p);
        assert_eq!(p.topic_str(), "pretendingToBeSomethingElse/any/anOutput");
    }

    println!("wildcard input plug: {:?}", input_wildcard_plug);
    println!("speific ID input plug: {:?}", input_customid_plug);

    let payload =
        rmp_serde::to_vec::<String>(&String::from("boo")).expect("failed to serialise payload");
    tether_agent
        .publish(&output_plug, Some(&payload))
        .expect("failed to publish");

    std::thread::sleep(Duration::from_millis(4000));
}
Source

pub fn base_path(self, base_path: Option<&str>) -> Self

Provide Some(value) to override or None to use default

Source

pub fn auto_connect(self, should_auto_connect: bool) -> Self

Source

pub fn build(self) -> Result<TetherAgent>

Examples found in repository?
examples/custom_options.rs (line 14)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
fn main() {
    let mut tether_agent = TetherAgentOptionsBuilder::new("example")
        .id(None)
        .host(Some("localhost"))
        .port(Some(1883))
        .username(Some("tether"))
        .password(Some("sp_ceB0ss!"))
        .build()
        .expect("failed to create Tether Agent");

    let output_plug = PlugOptionsBuilder::create_output("anOutput")
        .role(Some("pretendingToBeSomethingElse"))
        .qos(Some(2))
        .retain(Some(true))
        .build(&mut tether_agent)
        .expect("failed to create output plug");
    let input_wildcard_plug = PlugOptionsBuilder::create_input("everything")
        .topic(Some("#"))
        .build(&mut tether_agent);

    let input_customid_plug = PlugOptionsBuilder::create_input("someData")
        .role(None) // i.e., just use default
        .id(Some("specificIDonly"))
        .build(&mut tether_agent);

    println!("Agent looks like this: {:?}", tether_agent.description());
    let (role, id, _) = tether_agent.description();
    assert_eq!(role, "example");
    assert_eq!(id, "any"); // because we set None

    if let PlugDefinition::OutputPlug(p) = &output_plug {
        println!("output plug: {:?}", p);
        assert_eq!(p.topic_str(), "pretendingToBeSomethingElse/any/anOutput");
    }

    println!("wildcard input plug: {:?}", input_wildcard_plug);
    println!("speific ID input plug: {:?}", input_customid_plug);

    let payload =
        rmp_serde::to_vec::<String>(&String::from("boo")).expect("failed to serialise payload");
    tether_agent
        .publish(&output_plug, Some(&payload))
        .expect("failed to publish");

    std::thread::sleep(Duration::from_millis(4000));
}
More examples
Hide additional examples
examples/publish.rs (line 23)
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
fn main() {
    println!("Rust Tether Agent publish example");

    let mut builder = Builder::from_env(Env::default().default_filter_or("info"));
    builder.init();

    debug!("Debugging is enabled; could be verbose");

    let mut tether_agent = TetherAgentOptionsBuilder::new("RustDemo")
        .build()
        .expect("failed to connect Tether");
    let (role, id, _) = tether_agent.description();
    info!("Created agent OK: {}, {}", role, id);

    let empty_message_output = PlugOptionsBuilder::create_output("nothing")
        .build(&mut tether_agent)
        .expect("failed to create output");
    let boolean_message_output = PlugOptionsBuilder::create_output("one")
        .build(&mut tether_agent)
        .expect("failed to create output");
    let custom_output = PlugOptionsBuilder::create_output("two")
        .topic(Some("custom/custom/two"))
        .build(&mut tether_agent)
        .expect("failed to create output");
    let grouped_output_1 = PlugOptionsBuilder::create_output("one")
        .id(Some("groupMessages"))
        .build(&mut tether_agent)
        .expect("failed to create output");
    let grouped_output_2 = PlugOptionsBuilder::create_output("two")
        .id(Some("groupMessages"))
        .build(&mut tether_agent)
        .expect("failed to create output");

    for i in 1..=10 {
        info!("#{i}: Sending empty message...");
        tether_agent.publish(&empty_message_output, None).unwrap();

        let bool = i % 2 == 0;
        info!("#{i}: Sending boolean message...");
        tether_agent
            .publish(&boolean_message_output, Some(&[bool.into()]))
            .unwrap();

        info!("#{i}: Sending custom struct message...");
        let custom_message = CustomStruct {
            id: i,
            name: "hello".into(),
        };
        tether_agent
            .encode_and_publish(&custom_output, custom_message)
            .unwrap();

        info!("#{i}: Sending grouped messages...");
        tether_agent.publish(&grouped_output_1, None).unwrap();
        tether_agent.publish(&grouped_output_2, None).unwrap();

        thread::sleep(Duration::from_millis(1000))
    }
}
examples/subscribe.rs (line 29)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
fn main() {
    println!("Rust Tether Agent subscribe example");

    let mut builder = Builder::from_env(Env::default().default_filter_or("debug"));
    builder.filter_module("tether_agent", log::LevelFilter::Warn);
    builder.filter_module("rumqttc", log::LevelFilter::Warn);
    builder.init();

    debug!("Debugging is enabled; could be verbose");

    let mut tether_agent = TetherAgentOptionsBuilder::new("RustDemo")
        .id(Some("example"))
        .build()
        .expect("failed to init Tether agent");

    let input_one = PlugOptionsBuilder::create_input("one")
        .build(&mut tether_agent)
        .expect("failed to create input");
    info!("input one {} = {}", input_one.name(), input_one.topic());
    let input_two = PlugOptionsBuilder::create_input("two")
        .role(Some("specific"))
        .build(&mut tether_agent)
        .expect("failed to create input");
    info!("input two {} = {}", input_two.name(), input_two.topic());
    let input_empty = PlugOptionsBuilder::create_input("nothing")
        .build(&mut tether_agent)
        .expect("failed to create input");

    let input_everything = PlugOptionsBuilder::create_input("everything")
        .topic(Some("#"))
        .build(&mut tether_agent)
        .expect("failed to create input");

    let input_specify_id = PlugOptionsBuilder::create_input("groupMessages")
        .id(Some("someGroup"))
        .name(None)
        .build(&mut tether_agent)
        .expect("failed to create input");

    debug!(
        "input everything {} = {}",
        input_everything.name(),
        input_everything.topic()
    );

    info!("Checking messages every 1s, 10x...");

    loop {
        debug!("Checking for messages...");
        while let Some((topic, payload)) = tether_agent.check_messages() {
            // debug!(
            //     "........ Received a message topic {:?} => topic parts {:?}",
            //     topic, topic
            // );

            if input_one.matches(&topic) {
                info!(
                            "******** INPUT ONE:\n Received a message for plug named \"{}\" on topic {:?} with length {} bytes",
                            input_one.name(),
                            topic,
                            payload.len()
                        );
                // assert_eq!(parse_plug_name(topic.un), Some("one"));
            }
            if input_two.matches(&topic) {
                info!(
                        "******** INPUT TWO:\n Received a message for plug named \"{}\" on topic {:?} with length {} bytes",
                        input_two.name(),
                        topic,
                        payload.len()
                    );
                // assert_eq!(parse_plug_name(message.topic()), Some("two"));
                // assert_ne!(parse_plug_name(message.topic()), Some("one"));

                // Notice how you must give the from_slice function a type so it knows what to expect
                let decoded = from_slice::<CustomMessage>(&payload);
                match decoded {
                    Ok(d) => {
                        info!("Yes, we decoded the MessagePack payload as: {:?}", d);
                        let CustomMessage { name, id } = d;
                        debug!("Name is {} and ID is {}", name, id);
                    }
                    Err(e) => {
                        warn!("Failed to decode the payload: {}", e)
                    }
                };
            }
            if input_empty.matches(&topic) {
                info!(
                        "******** EMPTY MESSAGE:\n Received a message for plug named \"{}\" on topic {:?} with length {} bytes",
                        input_empty.name(),
                        topic,
                       payload.len()
                    );
                // assert_eq!(parse_plug_name(topic), Some("nothing"));
            }
            if input_everything.matches(&topic) {
                info!(
                    "******** EVERYTHING MATCHES HERE:\n Received a message for plug named \"{}\" on topic {:?} with length {} bytes",
                    input_everything.name(),
                    topic,
                   payload.len()
                );
            }
            if input_specify_id.matches(&topic) {
                info!("******** ID MATCH:\n Should match any role and plug name, but only messages with ID \"groupMessages\"");
                info!(
                    "\n Received a message from plug named \"{}\" on topic {:?} with length {} bytes",
                    input_specify_id.name(),
                    topic,
                    payload.len()
                );
                // assert_eq!(parse_agent_id(message.topic()), Some("groupMessages"));
            }
        }

        thread::sleep(Duration::from_millis(1000))
    }
}

Trait Implementations§

Source§

impl Clone for TetherAgentOptionsBuilder

Source§

fn clone(&self) -> TetherAgentOptionsBuilder

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> MaybeSendSync for T