1use serde::{Deserialize, Serialize};
8use simple_hyper_client::Method;
9use std::collections::HashMap;
10use std::fmt::Write;
11use uuid::Uuid;
12
13pub trait Operation {
14 type PathParams: for<'a> TupleRef<'a>;
15 type QueryParams: UrlEncode;
16 type Body: Serialize;
17 type Output: for<'de> Deserialize<'de>;
18
19 fn method() -> Method;
20 fn path(p: <Self::PathParams as TupleRef>::Ref, q: Option<&Self::QueryParams>) -> String;
21
22 fn to_body(body: &Self::Body) -> Option<serde_json::Value> {
23 Some(serde_json::to_value(body).expect("serialize to value"))
24 }
25}
26
27pub trait UrlEncode {
28 fn url_encode(&self, m: &mut HashMap<&'static str, String>);
29
30 fn encode(&self) -> String {
31 let mut m = HashMap::new();
32 self.url_encode(&mut m);
33 let mut output = String::with_capacity(64);
34 for (i, (k, v)) in m.into_iter().enumerate() {
35 if i > 0 {
36 output.push('&');
37 }
38 write!(&mut output, "{}={}", k, v).unwrap(); }
40 output
41 }
42}
43
44impl UrlEncode for () {
45 fn url_encode(&self, _m: &mut HashMap<&'static str, String>) {}
46}
47
48impl<T: UrlEncode> UrlEncode for Option<T> {
49 fn url_encode(&self, m: &mut HashMap<&'static str, String>) {
50 if let Some(val) = self {
51 val.url_encode(m);
52 }
53 }
54}
55
56impl<T: UrlEncode> UrlEncode for &T {
57 fn url_encode(&self, m: &mut HashMap<&'static str, String>) {
58 T::url_encode(self, m);
59 }
60}
61
62pub trait TupleRef<'a> {
63 type Ref: 'a;
64
65 fn as_ref(&'a self) -> Self::Ref;
66}
67
68impl<'a> TupleRef<'a> for Uuid {
69 type Ref = &'a Uuid;
70
71 fn as_ref(&'a self) -> Self::Ref {
72 self
73 }
74}
75
76impl<'a> TupleRef<'a> for String {
77 type Ref = &'a String;
78
79 fn as_ref(&'a self) -> Self::Ref {
80 self
81 }
82}
83
84impl<'a> TupleRef<'a> for () {
85 type Ref = ();
86
87 fn as_ref(&'a self) -> Self::Ref {
88 ()
89 }
90}
91
92impl<'a, T1: 'a> TupleRef<'a> for (T1,) {
93 type Ref = (&'a T1,);
94
95 fn as_ref(&'a self) -> Self::Ref {
96 (&self.0,)
97 }
98}
99
100impl<'a, T1: 'a, T2: 'a> TupleRef<'a> for (T1, T2) {
101 type Ref = (&'a T1, &'a T2);
102
103 fn as_ref(&'a self) -> Self::Ref {
104 (&self.0, &self.1)
105 }
106}
107
108impl<'a, T1: 'a, T2: 'a, T3: 'a> TupleRef<'a> for (T1, T2, T3) {
109 type Ref = (&'a T1, &'a T2, &'a T3);
110
111 fn as_ref(&'a self) -> Self::Ref {
112 (&self.0, &self.1, &self.2)
113 }
114}