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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

/// # `server` namespace
/// Has all the high level interactions to create and run a RESTful API server
///
/// ## Method
/// An enum of allowed operations on endpoints
///
/// ## Response
/// The response that the requester will receive (Headers, Content (Text or JSON), and parameters)
///
/// ## Request
/// The incoming request with Headers, Content (Text or JSON), and parameters
///
/// ## Endpoint
/// A combination of the operation method and a path string
///
/// ## Api
/// A collections of endpoints that can be run to start the REST server
mod server {
    use std;
    use std::collections::HashMap;

    /// # Method
    /// An enum of allowed operations on endpoints
    /// - `GET`
    /// - `PUT`
    /// - `POST`
    /// - `DELETE`
    /// - `OPTIONS`
    #[derive(Hash, PartialEq)]
    pub enum Method {
        GET,
        PUT,
        POST,
        DELETE,
        OPTIONS
    }
    pub struct Request;
    pub struct Response {
        pub code: u16
    }
    #[derive(Hash)]
    pub struct Endpoint {
        pub(crate) method: Method,
        pub(crate) path: String,
    }
    /// # Api
    /// A collections of endpoints that can be run to start the REST server
    ///
    /// ## Example
    /// ```
    /// use server;
    /// use std;
    ///
    /// let mut api = Api::new();
    /// fn handle_root_request(request: Request) -> Response {
    ///     println!("Received request on path '/'!");
    /// }
    /// api.add_endpoint(Method::GET, String::from("/"), handle_root_request);
    /// api.start();
    /// ```
    pub struct Api {
        pub(crate) endpoints: HashMap<Endpoint, fn(Request) -> Response>
    }

    impl Api {
        pub fn new() -> Api {
            return Api { endpoints : HashMap::new() };
        }

        pub fn add_endpoint(&mut self, method: Method, path: String, handler: fn(Request) -> Response) {
            let endpoint = Endpoint { method, path };
            self.endpoints.insert(endpoint, handler);
        }

        pub fn start() {

        }
    }

    impl PartialEq for Endpoint {
        fn eq(&self, other: &Self) -> bool {
            return self.method == other.method
                && self.path == other.path;
        }
    }
    impl Eq for Endpoint {}
}

#[cfg(test)]
mod tests {
    use super::*;

    fn api_test_handler(_request: server::Request) -> server::Response {
        println!("Received request");
        return server::Response { code: 200, }
    }

    #[test]
    fn test_adding_an_endpoint() {
        let mut api = server::Api::new();
        api.add_endpoint(server::Method::GET, String::from("/api/test"), api_test_handler);
        let my_model = server::Endpoint { method: server::Method::GET, path: String::from("/api/test") };
        assert!(api.endpoints.contains_key(&my_model));
    }
}