sdkms/
operations.rs

1/* Copyright (c) Fortanix, Inc.
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7use 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(); // FIXME: formurlencode
39        }
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}