1
2
3
4
5
6
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
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
136
137
138
139
140
141
/*!
# 📖 3.4. Ad-hoc Dialects
<em>[← Custom Processing](crate::docs::c3__custom_processing) | [Testing →](crate::docs::e3__testing)</em>
While in [Custom Dialects](crate::docs::c1__custom_dialects) we've explained how to generate custom
dialects from XML definitions, this chapter shows how one can create ad-hoc dialects using pure
Rust.
We call these dialects ad-hoc because they can be used only inside
[Mavka](https://mavka.gitlab.io/home/) toolchain and other tools are unable to process them.
That doesn't mean these dialects are useless. Quite opposite, by dedicating a particular segment of
message `ID` namespace to ad-hoc dialects, you may achieve interesting results.
## What is Small Talk?
Let's define a simple "small_talk" dialect:
```rust,no_run
use maviola::protocol::dialects::minimal::messages::Heartbeat;
use maviola::protocol::derive::{Dialect, Enum, Message};
use maviola::protocol::mavspec;
/// Communication mood.
#[repr(u8)]
#[derive(Copy, Clone, Debug, Default, Enum)]
pub enum Mood {
/// Speaks politely.
#[default]
Polite = 0,
/// Dead serious.
Serious = 1,
/// Not in the mood.
Grumpy = 2,
/// Delighted on the verge of delusion.
Delighted = 3,
/// Confused and distracted.
Confused = 4,
}
/// "How are you?" rhetorical question.
///
/// Well, maybe not always rhetorical.
#[derive(Clone, Debug, Message)]
#[message_id(72000)]
pub struct Howdy {
/// Communication mood.
#[base_type(u8)]
pub mood: Mood,
}
/// I'm good, fine.
#[derive(Clone, Debug, Message)]
#[message_id(72001)]
pub struct Good {
/// Communication mood.
#[base_type(u8)]
pub mood: Mood,
}
/// Returns the previous question
#[derive(Clone, Debug, Message)]
#[message_id(72002)]
pub struct AndYou {
/// Communication mood.
#[base_type(u8)]
pub mood: Mood,
}
/// A strange claim.
#[derive(Clone, Debug, Message)]
#[message_id(72003)]
pub struct NonSequitur {
/// Communication mood.
#[base_type(u8)]
pub mood: Mood,
}
/// Returned on confusion.
#[derive(Clone, Debug, Message)]
#[message_id(72004)]
pub struct Wat {
/// Communication mood.
#[base_type(u8)]
pub mood: Mood,
}
/// SmallTalk Ad-hoc Dialect.
#[derive(Dialect)]
#[dialect(1099)]
#[version(99)]
pub enum SmallTalk {
/// We want to be compatible with heartbeat protocol.
Heartbeat(Heartbeat),
/// — How are you?
Howdy(Howdy),
/// — Good.
Good(Good),
/// — And you?
AndYou(AndYou),
/// — I don't have a precise answer to your question. It was raining this morning. A black
/// terrier jumped over a bench scaring a flock of birds. My coffee becomes cold as I was
/// watching the clouds changing their elusive shape. When suddenly...
NonSequitur(NonSequitur),
/// — WAT!!!
Wat(Wat),
}
```
Looks okay for our purposes. If you want to know, how to build more complex messages, refer to
[MAVSpec](https://gitlab.com/mavka/libs/mavspec) documentation.
## Let's Have A Small Talk
Now, it is time to use our bespoke dialect. But this as simple, as using canonical dialects:
```rust,no_run
use maviola::prelude::*;
use maviola::sync::prelude::*;
use maviola::test_utils::smalltalk::*;
let node = Node::sync::<V2>()
.id(MavLinkId::new(1, 17))
.dialect::<SmallTalk>()
/* other node setting */
# .connection(TcpClient::new("127.0.0.1:5600").unwrap())
.build().unwrap();
node.send(&NonSequitur{
mood: Mood::Confused,
}).unwrap();
```
As you can see, we use [`maviola::test_utils`] module. This module contains utilities for testing.
To use it, you need to enable `test_utils` Cargo feature. Not the best choice for production but
can be useful for writing your own documentation.
<em>[← Custom Processing](crate::docs::c3__custom_processing) | [Guidelines →](crate::docs::e1__guidelines)</em>
[`maviola::test_utils`]: crate::test_utils
*/