aboutsummaryrefslogtreecommitdiff
path: root/src/message/signalproxy/translation.rs
blob: b765133a4adcd98be624cba9f50413364283ee5a (plain)
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//! Traits for Network Representation translation
//!
//! The traits found here usually do not need to implemented manually and can be derived using the [`libquassel::NetworkList`] and [`libquassel::NetworkMap`] macros.
//!
//! Quassel has 3 main ways to represent an object over the Network:
//!
//! ### VariantList
//! The struct is serialized to a Vector of Variants. This is mostly used in the InitData messages.
//! First the field name as a ByteArray (UTF-8 String), followed by the field value in it's own Type's va!iant.
//! The order in which the fields are transmitted cannot be assumed.
//!
//! Example:
//! ```ignore
//! NetworkConfig {
//!     ping_timeout_enabled: true,
//!     ping_interval: 0,
//! }
//! ```
//! to
//! ```ignore
//! VariantList([
//!     ByteArray(
//!         "pingTimeoutEnabled",
//!     ),
//!     bool(
//!         true,
//!     ),
//!     ByteArray(
//!         "pingInterval",
//!     ),
//!     i32(
//!         30,
//!     ),
//! ])
//! ```
//!
//!
//! ### VariantMap
//! The struct is represented as a `VariantMap`. The keys and values of
//! the struct are serialized to a corresponding `HashMap<String, Variant>`.
//!
//! Using the [libquassel::NetworkMap] macro this is selected with `#[network(repr = "map")]` on the object.
//!
//! Example:
//! ```ignore
//! NetworkConfig {
//!     ping_timeout_enabled: false,
//!     ping_interval: 0,
//! }
//! ```
//! to
//! ```ignore
//! VariantMap({
//!   "pingTimeoutEnabled": bool(false)
//!   "pingInterval": i32(0)
//! })
//! ```
//!
//! ### Structure of Arrays
//!
//! For Objects that are transmitted as multiple at once the VariantMap
//! representation is augemented and instead of transmitting multiple `VariantMaps`,
//! each field is a `VariantList` of Items.
//!
//! Using the [libquassel::NetworkMap] macro this is selected with `#[network(repr = "maplist")]` on the
//! object.
//!
//! Example:
//! ```ignore
//! vec![
//!     NetworkConfig {
//!         ping_timeout_enabled: false,
//!         ping_interval: 0,
//!     },
//!     NetworkConfig {
//!         ping_timeout_enabled: true,
//!         ping_interval: 1,
//!     },
//! ]
//! ```
//! to
//! ```ignore
//! VariantMap({
//!   "pingTimeoutEnabled": VariantList([
//!     bool(false),
//!     bool(true),
//!   ]),
//!   "pingInterval": VariantList([
//!     i32(0),
//!     i32(1),
//!   ])
//! })
//! ```
use crate::{
    primitive::{Variant, VariantList},
    ProtocolError, Result,
};

#[deprecated(
    since = "0.1.0",
    note = "please use NetworkMap and NetworkList implementations"
)]
pub trait Network {
    type Item;

    fn to_network(&self) -> Self::Item;
    fn from_network(input: &mut Self::Item) -> Self;
}

pub trait NetworkMap
where
    Self::Item: TryFrom<Variant, Error = ProtocolError>,
    Self::Item: Into<Variant>,
{
    type Item;

    fn to_network_map(&self) -> Result<Self::Item>;
    fn from_network_map(input: &mut Self::Item) -> Result<Self>
    where
        Self: std::marker::Sized;
}

pub trait NetworkList {
    fn to_network_list(&self) -> Result<VariantList>;
    fn from_network_list(input: VariantList) -> Result<Self>
    where
        Self: std::marker::Sized;
}

// impl<T: NetworkMap<Item = VariantMap>> NetworkList for T {
//     fn from_network_list(input: VariantList) -> Result<Self>
//     where
//         Self: std::marker::Sized + NetworkMap<Item = VariantMap>,
//     {
//         let mut i = input.into_iter();
//         let mut map: VariantMap = VariantMap::new();
//
//         while let Some(key) = i.next() {
//             let key: String = key.try_into()?;
//             let value = i.next().ok_or(ProtocolError::MissingField(key.clone()))?;
//             map.insert(key, value);
//         }
//
//         Self::from_network_map(&mut map)
//     }
//
//     fn to_network_list(&self) -> Result<VariantList> {
//         let map = Self::to_network_map(self)?;
//
//         let mut list = VariantList::new();
//         for (k, v) in map {
//             list.push(Variant::ByteArray(k));
//             list.push(v);
//         }
//
//         Ok(list)
//     }
// }