krpc_client/
lib.rs

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 {}