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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use std::fmt::Debug;

use regex::Regex;

use pillow_http::{controller::Controller, Request, Response};

/// Route
pub struct Route {
    method: pillow_http::http_methods::HttpMethods,
    /// uri path
    uri: pillow_http::Uri,

    /// Controller Callback Function
    controller: Controller,

    /// Parameters
    params: Vec<String>,

    /// Regex
    pub(crate) regex_complete: Regex,
    pub(crate) regex_words: Regex,
}

impl Debug for Route {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("Route")
            .field("method", &self.method)
            .field("uri", &self.uri)
            .field("params", &self.params)
            .finish()
    }
}

impl Route {
    pub fn uri(&self) -> &pillow_http::Uri {
        &self.uri
    }

    pub fn method(&self) -> &pillow_http::http_methods::HttpMethods {
        &self.method
    }

    pub fn params(&self) -> &Vec<String> {
        &self.params
    }

    pub fn regex_complete(&self) -> &Regex {
        &self.regex_complete
    }

    pub fn regex_words(&self) -> &Regex {
        &self.regex_words
    }
}

impl Route {
    /// New instance of Route
    ///
    /// # Arguments
    ///
    /// * `url` - Path of Route
    /// * `controller` - Callback function
    ///
    /// # Examples
    /// use pillow::http::Response
    ///
    /// ```rust
    /// Route::new("/".to_string(), pillow::http::HttpMethods::GET, |request| Response::text("hello"))
    /// ``
    pub fn new<T>(
        url: String,
        method: pillow_http::http_methods::HttpMethods,
        controller: T,
    ) -> Self
    where
        T: Fn(&Request) -> Response + Sync + Send + 'static,
    {
        let re = Regex::new(r"(<[a-zA-Z]+>)").unwrap();
        let regex_words = Regex::new(r"([a-zA-Z0-9]+)").unwrap();

        let params = if re.is_match(&url) {
            let param_with_more = re.find(&url).unwrap().as_str().to_string();

            let r = regex_words
                .find(&param_with_more)
                .unwrap()
                .as_str()
                .to_string();

            vec![r]
        } else {
            Vec::new()
        };

        let controller = Controller::new(controller);

        Self {
            method,
            uri: pillow_http::Uri(url),
            controller,
            params,
            regex_complete: re,
            regex_words,
        }
    }
}

impl Route {
    // Parameters methods
    pub fn has_parameters(&self) -> bool {
        self.params.len() > 0
    }

    /// Add Params
    pub fn add_parameters(&mut self, param: String) {
        self.params.push(param);
    }

    /// Get params
    pub fn get_parameters(&self) -> &Vec<String> {
        &self.params
    }

    /// Use controller
    pub(crate) fn use_controller(&self, request: &Request) -> Response {
        self.controller.use_action(request)
    }
}