1use custom_debug_derive::Debug;
7use linera_witty::{WitLoad, WitStore, WitType};
8use serde::{Deserialize, Serialize};
9
10use crate::hex_debug;
11
12#[derive(Clone, Debug, Eq, PartialEq, WitLoad, WitStore, WitType)]
14#[witty(name = "http-request")]
15pub struct Request {
16 pub method: Method,
18
19 pub url: String,
21
22 pub headers: Vec<Header>,
24
25 #[debug(with = "hex_debug")]
27 pub body: Vec<u8>,
28}
29
30impl Request {
31 pub fn get(url: impl Into<String>) -> Self {
33 Request {
34 method: Method::Get,
35 url: url.into(),
36 headers: vec![],
37 body: vec![],
38 }
39 }
40
41 pub fn post(url: impl Into<String>, payload: impl Into<Vec<u8>>) -> Self {
43 Request {
44 method: Method::Post,
45 url: url.into(),
46 headers: vec![],
47 body: payload.into(),
48 }
49 }
50
51 pub fn post_json(
54 url: impl Into<String>,
55 payload: &impl Serialize,
56 ) -> Result<Self, serde_json::Error> {
57 Ok(Request {
58 method: Method::Post,
59 url: url.into(),
60 headers: vec![Header::new("Content-Type", b"application/json")],
61 body: serde_json::to_vec(payload)?,
62 })
63 }
64
65 pub fn with_header(mut self, name: impl Into<String>, value: impl Into<Vec<u8>>) -> Self {
67 self.headers.push(Header::new(name, value));
68 self
69 }
70}
71
72#[derive(Clone, Copy, Debug, Eq, PartialEq, WitLoad, WitStore, WitType)]
74#[witty(name = "http-method")]
75pub enum Method {
76 Get,
78
79 Post,
81
82 Put,
84
85 Delete,
87
88 Head,
90
91 Options,
93
94 Connect,
96
97 Patch,
99
100 Trace,
102}
103
104#[cfg(with_reqwest)]
105impl From<Method> for reqwest::Method {
106 fn from(method: Method) -> Self {
107 match method {
108 Method::Get => reqwest::Method::GET,
109 Method::Post => reqwest::Method::POST,
110 Method::Put => reqwest::Method::PUT,
111 Method::Delete => reqwest::Method::DELETE,
112 Method::Head => reqwest::Method::HEAD,
113 Method::Options => reqwest::Method::OPTIONS,
114 Method::Connect => reqwest::Method::CONNECT,
115 Method::Patch => reqwest::Method::PATCH,
116 Method::Trace => reqwest::Method::TRACE,
117 }
118 }
119}
120
121#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize, WitLoad, WitStore, WitType)]
123#[witty(name = "http-response")]
124pub struct Response {
125 pub status: u16,
127
128 pub headers: Vec<Header>,
130
131 #[debug(with = "hex_debug")]
133 #[serde(with = "serde_bytes")]
134 pub body: Vec<u8>,
135}
136
137impl Response {
138 pub fn new(status_code: u16) -> Self {
140 Response {
141 status: status_code,
142 headers: vec![],
143 body: vec![],
144 }
145 }
146
147 pub fn ok(body: impl Into<Vec<u8>>) -> Self {
149 Response {
150 status: 200,
151 headers: vec![],
152 body: body.into(),
153 }
154 }
155
156 pub fn unauthorized() -> Self {
158 Response {
159 status: 401,
160 headers: vec![],
161 body: vec![],
162 }
163 }
164
165 pub fn with_header(mut self, name: impl Into<String>, value: impl Into<Vec<u8>>) -> Self {
167 self.headers.push(Header::new(name, value));
168 self
169 }
170}
171
172#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize, WitLoad, WitStore, WitType)]
174#[witty(name = "http-header")]
175pub struct Header {
176 pub name: String,
178
179 #[debug(with = "hex_debug")]
181 #[serde(with = "serde_bytes")]
182 pub value: Vec<u8>,
183}
184
185impl Header {
186 pub fn new(name: impl Into<String>, value: impl Into<Vec<u8>>) -> Self {
188 Header {
189 name: name.into(),
190 value: value.into(),
191 }
192 }
193}