Skip to main content

orpc_procedure/
route.rs

1/// HTTP method for route matching.
2#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3pub enum HttpMethod {
4    Get,
5    Post,
6    Put,
7    Delete,
8    Patch,
9    Head,
10    Options,
11}
12
13impl std::fmt::Display for HttpMethod {
14    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15        f.write_str(match self {
16            HttpMethod::Get => "GET",
17            HttpMethod::Post => "POST",
18            HttpMethod::Put => "PUT",
19            HttpMethod::Delete => "DELETE",
20            HttpMethod::Patch => "PATCH",
21            HttpMethod::Head => "HEAD",
22            HttpMethod::Options => "OPTIONS",
23        })
24    }
25}
26
27/// HTTP route metadata for a procedure.
28///
29/// Carries method, path, tags, and OpenAPI documentation fields.
30#[derive(Debug, Clone, Default)]
31pub struct Route {
32    pub method: Option<HttpMethod>,
33    pub path: Option<String>,
34    pub tags: Vec<String>,
35    pub summary: Option<String>,
36    pub description: Option<String>,
37    pub deprecated: bool,
38}
39
40impl Route {
41    pub fn new() -> Self {
42        Self::default()
43    }
44
45    pub fn get(path: impl Into<String>) -> Self {
46        Route {
47            method: Some(HttpMethod::Get),
48            path: Some(path.into()),
49            ..Default::default()
50        }
51    }
52
53    pub fn post(path: impl Into<String>) -> Self {
54        Route {
55            method: Some(HttpMethod::Post),
56            path: Some(path.into()),
57            ..Default::default()
58        }
59    }
60
61    pub fn put(path: impl Into<String>) -> Self {
62        Route {
63            method: Some(HttpMethod::Put),
64            path: Some(path.into()),
65            ..Default::default()
66        }
67    }
68
69    pub fn delete(path: impl Into<String>) -> Self {
70        Route {
71            method: Some(HttpMethod::Delete),
72            path: Some(path.into()),
73            ..Default::default()
74        }
75    }
76
77    pub fn patch(path: impl Into<String>) -> Self {
78        Route {
79            method: Some(HttpMethod::Patch),
80            path: Some(path.into()),
81            ..Default::default()
82        }
83    }
84
85    pub fn tag(mut self, tag: impl Into<String>) -> Self {
86        self.tags.push(tag.into());
87        self
88    }
89
90    pub fn summary(mut self, summary: impl Into<String>) -> Self {
91        self.summary = Some(summary.into());
92        self
93    }
94
95    pub fn description(mut self, description: impl Into<String>) -> Self {
96        self.description = Some(description.into());
97        self
98    }
99
100    pub fn deprecated(mut self) -> Self {
101        self.deprecated = true;
102        self
103    }
104}
105
106/// Extensible procedure metadata. Empty for Phase 1a.
107#[derive(Debug, Clone, Default)]
108pub struct Meta {}
109
110/// Error map stub. Full implementation in Phase 1b with Schema trait.
111#[derive(Debug, Clone, Default)]
112pub struct ErrorMap {}
113
114#[cfg(test)]
115mod tests {
116    use super::*;
117
118    #[test]
119    fn route_default() {
120        let route = Route::new();
121        assert!(route.method.is_none());
122        assert!(route.path.is_none());
123        assert!(route.tags.is_empty());
124        assert!(!route.deprecated);
125    }
126
127    #[test]
128    fn route_get_builder() {
129        let route = Route::get("/users")
130            .tag("users")
131            .tag("admin")
132            .summary("List users")
133            .description("Returns all users")
134            .deprecated();
135
136        assert_eq!(route.method, Some(HttpMethod::Get));
137        assert_eq!(route.path.as_deref(), Some("/users"));
138        assert_eq!(route.tags, vec!["users", "admin"]);
139        assert_eq!(route.summary.as_deref(), Some("List users"));
140        assert_eq!(route.description.as_deref(), Some("Returns all users"));
141        assert!(route.deprecated);
142    }
143
144    #[test]
145    fn route_post() {
146        let route = Route::post("/users");
147        assert_eq!(route.method, Some(HttpMethod::Post));
148        assert_eq!(route.path.as_deref(), Some("/users"));
149    }
150
151    #[test]
152    fn route_clone() {
153        let route = Route::get("/test").tag("api");
154        let cloned = route.clone();
155        assert_eq!(cloned.path, route.path);
156        assert_eq!(cloned.tags, route.tags);
157    }
158
159    #[test]
160    fn meta_default() {
161        let _meta = Meta::default();
162    }
163
164    #[test]
165    fn error_map_default() {
166        let _map = ErrorMap::default();
167    }
168}