1pub mod client;
2pub mod error;
3pub mod stream;
4
5pub use client::Client;
6
7pub mod services {
8 include!(concat!(env!("OUT_DIR"), "/services.rs"));
9}
10
11mod schema {
12 use std::{
13 collections::{HashMap, HashSet},
14 hash::Hash,
15 sync::Arc,
16 };
17
18 pub use krpc::*;
19 use protobuf::Message;
20
21 use crate::{client::Client, error::RpcError};
22
23 include!(concat!(env!("OUT_DIR"), "/krpc.rs"));
24 pub trait DecodeUntagged: Sized {
25 fn decode_untagged(
26 client: Arc<Client>,
27 buf: &[u8],
28 ) -> Result<Self, RpcError>;
29 }
30
31 pub trait FromResponse: Sized {
32 fn from_response(
33 response: Response,
34 client: Arc<Client>,
35 ) -> Result<Self, RpcError>;
36 }
37
38 impl DecodeUntagged for () {
39 fn decode_untagged(
40 _client: Arc<Client>,
41 _buf: &[u8],
42 ) -> Result<Self, RpcError> {
43 Ok(())
44 }
45 }
46
47 impl<T: DecodeUntagged> FromResponse for T {
48 fn from_response(
49 response: Response,
50 client: Arc<Client>,
51 ) -> Result<T, RpcError> {
52 Self::decode_untagged(client, &response.results[0].value)
53 }
54 }
55
56 pub trait ToArgument {
57 fn to_argument(&self, pos: u32) -> Result<Argument, RpcError>;
58 }
59
60 pub trait EncodeUntagged {
61 fn encode_untagged(&self) -> Result<Vec<u8>, RpcError>;
62 }
63
64 impl<T: EncodeUntagged> ToArgument for T {
65 fn to_argument(&self, pos: u32) -> Result<Argument, RpcError> {
66 Ok(Argument {
67 position: pos,
68 value: self.encode_untagged()?,
69 ..Default::default()
70 })
71 }
72 }
73
74 impl<T: EncodeUntagged> EncodeUntagged for &T {
75 fn encode_untagged(&self) -> Result<Vec<u8>, RpcError> {
76 (*self).encode_untagged()
77 }
78 }
79
80 macro_rules! encode_untagged {
81 ($t:ty, $fname:ident) => {
82 impl EncodeUntagged for $t {
83 fn encode_untagged(&self) -> Result<Vec<u8>, RpcError> {
84 let mut buf: Vec<u8> = Vec::new();
85 {
86 let mut outstream =
87 protobuf::CodedOutputStream::new(&mut buf);
88 outstream
89 .$fname(*self)
90 .map_err(|e| RpcError::from(e))?;
91 outstream.flush().map_err(|e| RpcError::from(e))?;
92 }
93
94 Ok(buf)
95 }
96 }
97 };
98 }
99
100 macro_rules! rpc_object {
101 ($name:ident) => {
102 pub struct $name {
103 id: u64,
104 client: ::std::sync::Arc<crate::client::Client>,
105 }
106
107 impl crate::schema::DecodeUntagged for $name {
108 fn decode_untagged(
109 client: ::std::sync::Arc<crate::client::Client>,
110 buf: &[u8],
111 ) -> Result<Self, RpcError> {
112 Ok($name {
113 id: u64::decode_untagged(client.clone(), buf)?,
114 client,
115 })
116 }
117 }
118
119 impl crate::schema::EncodeUntagged for $name {
120 fn encode_untagged(&self) -> Result<Vec<u8>, RpcError> {
121 self.id.encode_untagged()
122 }
123 }
124 };
125 }
126
127 macro_rules! rpc_enum {
128 ($name:ident, [$($value:ident),+$(,)?]) => {
129 #[derive(Debug, Copy, Clone, PartialEq)]
130 pub enum $name {$(
131 $value,
132 )+}
133
134 impl crate::schema::DecodeUntagged for $name {
135 fn decode_untagged(
136 client: ::std::sync::Arc<crate::client::Client>,
137 buf: &[u8]
138 ) -> Result<Self, RpcError> {
139 match i32::decode_untagged(client, buf)? {
140 $(i if i == $name::$value as i32 => Ok($name::$value),)+
141 _ => Err(RpcError::Encoding("invalid enum variant".into()))
142 }
143 }
144 }
145
146 impl crate::schema::EncodeUntagged for $name {
147 fn encode_untagged(&self) -> Result<Vec<u8>, RpcError> {
148 (*self as i32).encode_untagged()
149 }
150 }
151 }
152 }
153
154 macro_rules! decode_untagged {
155 ($to:ty, $proto:ident) => {
156 impl DecodeUntagged for $to {
157 fn decode_untagged(
158 _: ::std::sync::Arc<crate::client::Client>,
159 b: &[u8],
160 ) -> Result<Self, RpcError> {
161 ::protobuf::CodedInputStream::from_bytes(b)
162 .$proto()
163 .map_err(|e| e.into())
164 }
165 }
166 };
167 }
168
169 macro_rules! encode_decode_message_untagged {
170 ($($m:ty),+$(,)?) => {$(
171 impl DecodeUntagged for $m {
172 fn decode_untagged(
173 _: ::std::sync::Arc<crate::client::Client>,
174 b: &[u8]
175 ) -> Result<Self, RpcError> {
176 Self::parse_from_bytes(&b[..]).map_err(|e| RpcError::from(e))
177 }
178 }
179
180 impl EncodeUntagged for $m {
181 fn encode_untagged(&self) -> Result<Vec<u8>, RpcError> {
182 let mut v = Vec::new();
183 self.write_to_vec(&mut v)?;
184 Ok(v)
185 }
186 })+
187 };
188 }
189
190 impl From<ProcedureCall> for Request {
191 fn from(proc_call: ProcedureCall) -> Self {
192 Request {
193 calls: vec![proc_call],
194 ..Default::default()
195 }
196 }
197 }
198
199 impl<T0, T1> DecodeUntagged for (T0, T1)
200 where
201 T0: DecodeUntagged,
202 T1: DecodeUntagged,
203 {
204 fn decode_untagged(
205 client: Arc<Client>,
206 buf: &[u8],
207 ) -> Result<Self, RpcError> {
208 let tuple = Tuple::decode_untagged(client.clone(), buf)?;
209 Ok((
210 T0::decode_untagged(
211 client.clone(),
212 tuple.items.first().ok_or(RpcError::Encoding(
213 "tuple element out of range".into(),
214 ))?,
215 )?,
216 T1::decode_untagged(
217 client,
218 tuple.items.get(1).ok_or(RpcError::Encoding(
219 "tuple element out of range".into(),
220 ))?,
221 )?,
222 ))
223 }
224 }
225
226 impl<T0, T1> EncodeUntagged for (T0, T1)
227 where
228 T0: EncodeUntagged,
229 T1: EncodeUntagged,
230 {
231 fn encode_untagged(&self) -> Result<Vec<u8>, RpcError> {
232 Tuple {
233 items: vec![
234 self.0.encode_untagged()?,
235 self.1.encode_untagged()?,
236 ],
237 ..Default::default()
238 }
239 .encode_untagged()
240 }
241 }
242
243 impl<T0, T1, T2> DecodeUntagged for (T0, T1, T2)
244 where
245 T0: DecodeUntagged,
246 T1: DecodeUntagged,
247 T2: DecodeUntagged,
248 {
249 fn decode_untagged(
250 client: Arc<Client>,
251 buf: &[u8],
252 ) -> Result<Self, RpcError> {
253 let tuple = Tuple::decode_untagged(client.clone(), buf)?;
254 Ok((
255 T0::decode_untagged(
256 client.clone(),
257 tuple.items.first().ok_or(RpcError::Encoding(
258 "tuple element out of range".into(),
259 ))?,
260 )?,
261 T1::decode_untagged(
262 client.clone(),
263 tuple.items.get(1).ok_or(RpcError::Encoding(
264 "tuple element out of range".into(),
265 ))?,
266 )?,
267 T2::decode_untagged(
268 client,
269 tuple.items.get(2).ok_or(RpcError::Encoding(
270 "tuple element out of range".into(),
271 ))?,
272 )?,
273 ))
274 }
275 }
276
277 impl<T0, T1, T2> EncodeUntagged for (T0, T1, T2)
278 where
279 T0: EncodeUntagged,
280 T1: EncodeUntagged,
281 T2: EncodeUntagged,
282 {
283 fn encode_untagged(&self) -> Result<Vec<u8>, RpcError> {
284 Tuple {
285 items: vec![
286 self.0.encode_untagged()?,
287 self.1.encode_untagged()?,
288 self.2.encode_untagged()?,
289 ],
290 ..Default::default()
291 }
292 .encode_untagged()
293 }
294 }
295
296 impl<T0, T1, T2, T3> DecodeUntagged for (T0, T1, T2, T3)
297 where
298 T0: DecodeUntagged,
299 T1: DecodeUntagged,
300 T2: DecodeUntagged,
301 T3: DecodeUntagged,
302 {
303 fn decode_untagged(
304 client: Arc<Client>,
305 buf: &[u8],
306 ) -> Result<Self, RpcError> {
307 let tuple = Tuple::decode_untagged(client.clone(), buf)?;
308 Ok((
309 T0::decode_untagged(
310 client.clone(),
311 tuple.items.first().ok_or(RpcError::Encoding(
312 "tuple element out of range".into(),
313 ))?,
314 )?,
315 T1::decode_untagged(
316 client.clone(),
317 tuple.items.get(1).ok_or(RpcError::Encoding(
318 "tuple element out of range".into(),
319 ))?,
320 )?,
321 T2::decode_untagged(
322 client.clone(),
323 tuple.items.get(2).ok_or(RpcError::Encoding(
324 "tuple element out of range".into(),
325 ))?,
326 )?,
327 T3::decode_untagged(
328 client,
329 tuple.items.get(3).ok_or(RpcError::Encoding(
330 "tuple element out of range".into(),
331 ))?,
332 )?,
333 ))
334 }
335 }
336
337 impl<T0, T1, T2, T3> EncodeUntagged for (T0, T1, T2, T3)
338 where
339 T0: EncodeUntagged,
340 T1: EncodeUntagged,
341 T2: EncodeUntagged,
342 T3: EncodeUntagged,
343 {
344 fn encode_untagged(&self) -> Result<Vec<u8>, RpcError> {
345 Tuple {
346 items: vec![
347 self.0.encode_untagged()?,
348 self.1.encode_untagged()?,
349 self.2.encode_untagged()?,
350 self.3.encode_untagged()?,
351 ],
352 ..Default::default()
353 }
354 .encode_untagged()
355 }
356 }
357
358 impl<K, V> DecodeUntagged for HashMap<K, V>
359 where
360 K: DecodeUntagged + Eq + Hash + Default,
361 V: DecodeUntagged,
362 {
363 fn decode_untagged(
364 client: Arc<Client>,
365 buf: &[u8],
366 ) -> Result<Self, RpcError> {
367 let mut map: HashMap<K, V> = HashMap::new();
368 let dictionary = Dictionary::decode_untagged(client.clone(), buf)?;
369 for entry in dictionary.entries.into_iter() {
370 map.insert(
371 K::decode_untagged(client.clone(), &entry.key)?,
372 V::decode_untagged(client.clone(), &entry.value)?,
373 );
374 }
375 Ok(map)
376 }
377 }
378
379 impl<K, V> EncodeUntagged for HashMap<K, V>
380 where
381 K: EncodeUntagged,
382 V: EncodeUntagged,
383 {
384 fn encode_untagged(&self) -> Result<Vec<u8>, RpcError> {
385 let mut entries = Vec::new();
386
387 for (k, v) in self {
388 entries.push(DictionaryEntry {
389 key: k.encode_untagged()?,
390 value: v.encode_untagged()?,
391 ..Default::default()
392 })
393 }
394
395 Dictionary {
396 entries,
397 ..Default::default()
398 }
399 .encode_untagged()
400 }
401 }
402
403 impl<T> DecodeUntagged for HashSet<T>
404 where
405 T: DecodeUntagged + Eq + Hash,
406 {
407 fn decode_untagged(
408 client: Arc<Client>,
409 buf: &[u8],
410 ) -> Result<Self, RpcError> {
411 let protoset = Set::decode_untagged(client.clone(), buf)?;
412 let mut set = HashSet::new();
413
414 for item in protoset.items.into_iter() {
415 set.insert(T::decode_untagged(client.clone(), &item)?);
416 }
417
418 Ok(set)
419 }
420 }
421
422 impl<T> EncodeUntagged for HashSet<T>
423 where
424 T: EncodeUntagged,
425 {
426 fn encode_untagged(&self) -> Result<Vec<u8>, RpcError> {
427 let mut items = Vec::new();
428 for item in self.iter() {
429 items.push(item.encode_untagged()?);
430 }
431
432 Set {
433 items,
434 ..Default::default()
435 }
436 .encode_untagged()
437 }
438 }
439
440 impl<T> DecodeUntagged for Vec<T>
441 where
442 T: DecodeUntagged,
443 {
444 fn decode_untagged(
445 client: Arc<Client>,
446 buf: &[u8],
447 ) -> Result<Self, RpcError> {
448 let mut v = Vec::new();
449 for item in List::decode_untagged(client.clone(), buf)?
450 .items
451 .into_iter()
452 {
453 v.push(T::decode_untagged(client.clone(), &item)?);
454 }
455
456 Ok(v)
457 }
458 }
459
460 impl<T> EncodeUntagged for Vec<T>
461 where
462 T: EncodeUntagged,
463 {
464 fn encode_untagged(&self) -> Result<Vec<u8>, RpcError> {
465 let mut items = Vec::new();
466 for item in self.iter() {
467 items.push(item.encode_untagged()?);
468 }
469
470 List {
471 items,
472 ..Default::default()
473 }
474 .encode_untagged()
475 }
476 }
477
478 impl EncodeUntagged for String {
479 fn encode_untagged(&self) -> Result<Vec<u8>, RpcError> {
480 let mut buf: Vec<u8> = Vec::new();
481 {
482 let mut os = protobuf::CodedOutputStream::new(&mut buf);
483 os.write_string_no_tag(self).map_err(RpcError::from)?;
484 os.flush().map_err(RpcError::from)?;
485 }
486
487 Ok(buf)
488 }
489 }
490
491 impl<T: DecodeUntagged> DecodeUntagged for Option<T> {
492 fn decode_untagged(
493 client: Arc<Client>,
494 buf: &[u8],
495 ) -> Result<Self, RpcError> {
496 if buf == [0u8] {
497 Ok(None)
498 } else {
499 Some(T::decode_untagged(client, buf)).transpose()
500 }
501 }
502 }
503
504 impl<T: EncodeUntagged> EncodeUntagged for Option<T> {
505 fn encode_untagged(&self) -> Result<Vec<u8>, RpcError> {
506 match self {
507 Some(t) => t.encode_untagged(),
508 None => Ok(vec![0u8]),
509 }
510 }
511 }
512
513 decode_untagged!(String, read_string);
514 decode_untagged!(bool, read_bool);
515 decode_untagged!(f32, read_float);
516 decode_untagged!(f64, read_double);
517 decode_untagged!(i32, read_sint32);
518 decode_untagged!(u32, read_uint32);
519 decode_untagged!(u64, read_uint64);
520 decode_untagged!(Vec<u8>, read_bytes);
521
522 encode_decode_message_untagged!(
523 Dictionary,
524 List,
525 Set,
526 Status,
527 Stream,
528 Services,
529 ProcedureCall,
530 ProcedureResult,
531 Event,
532 Tuple
533 );
534
535 encode_untagged!(bool, write_bool_no_tag);
536 encode_untagged!(i32, write_sint32_no_tag);
537 encode_untagged!(u32, write_uint32_no_tag);
538 encode_untagged!(f32, write_float_no_tag);
539 encode_untagged!(f64, write_double_no_tag);
540 encode_untagged!(u64, write_uint64_no_tag);
541
542 pub(crate) use rpc_enum;
543 pub(crate) use rpc_object;
544}
545
546pub trait RpcType: schema::DecodeUntagged {}
547
548impl<T: schema::DecodeUntagged> RpcType for T {}