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
#![feature(try_trait)]
extern crate serde;
use serde::{Serialize, de::DeserializeOwned};
use std::fmt::Display;
use std::option::NoneError;
pub enum Error {
Fetch(String),
SerDe(String),
NotFound(String),
Authorization(String),
}
impl From<NoneError> for Error {
fn from(_: NoneError) -> Error {
Error::NotFound(String::from("Expected a value, found None"))
}
}
pub trait Provider<P> {
type Data: Endpoint;
fn get(provider: &P, id: <Self::Data as Endpoint>::Id) -> Result<Self::Data, Error>;
fn list(provider: &P, query: Self::Data) -> Vec<Self::Data>;
fn create(provider: &P, query: Self::Data) -> Result<Self::Data, Error>;
fn update(provider: &P, id: <Self::Data as Endpoint>::Id, new_data: Self::Data) -> Result<Self::Data, Error>;
fn delete(provider: &P, id: <Self::Data as Endpoint>::Id);
}
pub trait Endpoint: Default + Serialize + DeserializeOwned {
type Id: Display;
fn endpoint() -> &'static str;
fn get<F: Fetch>(&self, id: Self::Id) -> Result<Self, Error> {
F::fetch("GET", format!("{}/{}", Self::endpoint(), id), None)
}
fn list<F: Fetch>(&self) -> Result<Self, Error> {
F::fetch("GET", format!("{}", Self::endpoint()), None)
}
fn find<F: Fetch>(&self, query: Self) -> Result<Self, Error> {
F::fetch("GET", format!("{}", Self::endpoint()), Some(query))
}
fn create<F: Fetch>(&self, new: Self) -> Result<Self, Error> {
F::fetch("POST", format!("{}", Self::endpoint()), Some(new))
}
fn update<F: Fetch>(&self, id: Self::Id, data: Self) -> Result<Self, Error> {
F::fetch("PUT", format!("{}/{}", Self::endpoint(), id), Some(data))
}
fn delete<F: Fetch>(&self, id: Self::Id) -> Result<Self, Error> {
F::fetch("DELETE", format!("{}/{}", Self::endpoint(), id), None)
}
}
pub trait Fetch {
fn fetch<T: Endpoint>(method: &'static str, url: String, query: Option<T>) -> Result<T, Error>;
}