1use crate::error::{ParseError, ParserResult};
2use crate::hir;
3use serde::{Deserialize, Serialize};
4
5#[cfg(test)]
6mod tests;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
9pub enum HttpMethod {
10 Get,
11 Post,
12 Put,
13 Patch,
14 Delete,
15 Head,
16 Options,
17}
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
20pub enum HttpParamKind {
21 Path,
22 Query,
23 Header,
24 Cookie,
25 Body,
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
29pub enum HttpOperationSource {
30 Method,
31 AttributeGet,
32 AttributeSet,
33 AttributeWatch,
34}
35
36#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
37pub struct HttpRoute {
38 pub path: String,
39 pub path_params: Vec<String>,
40 pub query_params: Vec<String>,
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct HttpParam {
45 pub name: String,
46 pub wire_name: String,
47 pub ty: hir::TypeSpec,
48 pub kind: HttpParamKind,
49 pub optional: bool,
50 pub flatten: bool,
51}
52
53#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
54pub struct HttpDocumentServer {
55 pub base_url: String,
56 pub description: Option<String>,
57}
58
59#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
60pub struct HttpDocumentMetadata {
61 pub package: Option<String>,
62 pub version: Option<String>,
63 pub servers: Vec<HttpDocumentServer>,
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize)]
67pub struct HttpOperation {
68 pub name: String,
69 pub operation_id: String,
70 pub source: HttpOperationSource,
71 pub method: HttpMethod,
72 pub routes: Vec<HttpRoute>,
73 pub stream: super::semantics::HttpStreamConfig,
74 pub request_content_type: String,
75 pub response_content_type: String,
76 pub security: Option<super::semantics::HttpSecurityProfile>,
77 pub basic_auth_realm: Option<String>,
78 pub deprecated: Option<super::semantics::DeprecatedInfo>,
79 pub request_params: Vec<HttpParam>,
80 pub response_params: Vec<HttpParam>,
81 pub return_type: Option<hir::TypeSpec>,
82}
83
84#[derive(Debug, Clone, Serialize, Deserialize)]
85pub struct HttpInterface {
86 pub name: String,
87 pub module_path: Vec<String>,
88 pub operations: Vec<HttpOperation>,
89}
90
91#[derive(Debug, Clone, Serialize, Deserialize)]
92pub struct RestHirDocument {
93 pub spec: hir::Specification,
94 pub document: HttpDocumentMetadata,
95 pub interfaces: Vec<HttpInterface>,
96}
97
98impl RestHirDocument {
99 pub fn from_props(props: &hir::ParserProperties) -> ParserResult<Self> {
100 let value = props
101 .get("rest_hir")
102 .cloned()
103 .ok_or_else(|| ParseError::Message("missing rest_hir properties".to_string()))?;
104 serde_json::from_value(value).map_err(|err| ParseError::Message(err.to_string()))
105 }
106
107 pub fn find_interface(&self, module_path: &[String], name: &str) -> Option<&HttpInterface> {
108 self.interfaces
109 .iter()
110 .find(|interface| interface.name == name && interface.module_path == module_path)
111 }
112}