1use allocative::Allocative;
7use custom_debug_derive::Debug;
8use linera_witty::{WitLoad, WitStore, WitType};
9use serde::{Deserialize, Serialize};
10
11use crate::hex_debug;
12
13#[derive(Clone, Debug, Eq, PartialEq, WitLoad, WitStore, WitType)]
15#[witty(name = "http-request")]
16pub struct Request {
17 pub method: Method,
19
20 pub url: String,
22
23 pub headers: Vec<Header>,
25
26 #[debug(with = "hex_debug")]
28 pub body: Vec<u8>,
29}
30
31impl Request {
32 pub fn get(url: impl Into<String>) -> Self {
34 Request {
35 method: Method::Get,
36 url: url.into(),
37 headers: vec![],
38 body: vec![],
39 }
40 }
41
42 pub fn post(url: impl Into<String>, payload: impl Into<Vec<u8>>) -> Self {
44 Request {
45 method: Method::Post,
46 url: url.into(),
47 headers: vec![],
48 body: payload.into(),
49 }
50 }
51
52 pub fn post_json(
55 url: impl Into<String>,
56 payload: &impl Serialize,
57 ) -> Result<Self, serde_json::Error> {
58 Ok(Request {
59 method: Method::Post,
60 url: url.into(),
61 headers: vec![Header::new("Content-Type", b"application/json")],
62 body: serde_json::to_vec(payload)?,
63 })
64 }
65
66 pub fn with_header(mut self, name: impl Into<String>, value: impl Into<Vec<u8>>) -> Self {
68 self.headers.push(Header::new(name, value));
69 self
70 }
71}
72
73#[derive(Clone, Copy, Debug, Eq, PartialEq, WitLoad, WitStore, WitType)]
75#[witty(name = "http-method")]
76pub enum Method {
77 Get,
79
80 Post,
82
83 Put,
85
86 Delete,
88
89 Head,
91
92 Options,
94
95 Connect,
97
98 Patch,
100
101 Trace,
103}
104
105#[cfg(with_reqwest)]
106impl From<Method> for reqwest::Method {
107 fn from(method: Method) -> Self {
108 match method {
109 Method::Get => reqwest::Method::GET,
110 Method::Post => reqwest::Method::POST,
111 Method::Put => reqwest::Method::PUT,
112 Method::Delete => reqwest::Method::DELETE,
113 Method::Head => reqwest::Method::HEAD,
114 Method::Options => reqwest::Method::OPTIONS,
115 Method::Connect => reqwest::Method::CONNECT,
116 Method::Patch => reqwest::Method::PATCH,
117 Method::Trace => reqwest::Method::TRACE,
118 }
119 }
120}
121
122#[derive(
124 Clone,
125 Debug,
126 Deserialize,
127 Eq,
128 Hash,
129 PartialEq,
130 Serialize,
131 WitLoad,
132 WitStore,
133 WitType,
134 Allocative,
135)]
136#[witty(name = "http-response")]
137pub struct Response {
138 pub status: u16,
140
141 pub headers: Vec<Header>,
143
144 #[debug(with = "hex_debug")]
146 #[serde(with = "serde_bytes")]
147 pub body: Vec<u8>,
148}
149
150impl Response {
151 pub fn new(status_code: u16) -> Self {
153 Response {
154 status: status_code,
155 headers: vec![],
156 body: vec![],
157 }
158 }
159
160 pub fn ok(body: impl Into<Vec<u8>>) -> Self {
162 Response {
163 status: 200,
164 headers: vec![],
165 body: body.into(),
166 }
167 }
168
169 pub fn unauthorized() -> Self {
171 Response {
172 status: 401,
173 headers: vec![],
174 body: vec![],
175 }
176 }
177
178 pub fn with_header(mut self, name: impl Into<String>, value: impl Into<Vec<u8>>) -> Self {
180 self.headers.push(Header::new(name, value));
181 self
182 }
183}
184
185#[derive(
187 Clone,
188 Debug,
189 Deserialize,
190 Eq,
191 Hash,
192 PartialEq,
193 Serialize,
194 WitLoad,
195 WitStore,
196 WitType,
197 Allocative,
198)]
199#[witty(name = "http-header")]
200pub struct Header {
201 pub name: String,
203
204 #[debug(with = "hex_debug")]
206 #[serde(with = "serde_bytes")]
207 pub value: Vec<u8>,
208}
209
210impl Header {
211 pub fn new(name: impl Into<String>, value: impl Into<Vec<u8>>) -> Self {
213 Header {
214 name: name.into(),
215 value: value.into(),
216 }
217 }
218}