Skip to content

Commit 8df9fc4

Browse files
authored
Merge pull request #10 from supabase/feature/range
Add open-ended range for limit and auth with JWT token
2 parents fd9feab + 5857a92 commit 8df9fc4

File tree

1 file changed

+43
-24
lines changed

1 file changed

+43
-24
lines changed

src/builder.rs

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use reqwest::{Client, Error, Method, Response};
1+
use reqwest::{
2+
header::{HeaderMap, HeaderValue},
3+
Client, Error, Method, Response,
4+
};
25

36
macro_rules! filter {
47
( $( $op:ident ),* ) => {
@@ -19,7 +22,7 @@ pub struct Builder {
1922
schema: Option<String>,
2023
queries: Vec<(String, String)>,
2124
// TODO: Maybe change to HeaderMap in the future
22-
headers: Vec<(String, String)>,
25+
headers: HeaderMap,
2326
body: Option<String>,
2427
is_rpc: bool,
2528
}
@@ -34,10 +37,19 @@ impl Builder {
3437
method: Method::GET,
3538
url: url.to_string(),
3639
schema,
40+
headers: HeaderMap::new(),
3741
..Default::default()
3842
}
3943
}
4044

45+
pub fn auth(mut self, token: &str) -> Self {
46+
self.headers.append(
47+
"Authorization",
48+
HeaderValue::from_str(&format!("Bearer {}", token)).unwrap(),
49+
);
50+
self
51+
}
52+
4153
// TODO: Multiple columns
4254
// TODO: Renaming columns
4355
// TODO: Casting columns
@@ -60,18 +72,27 @@ impl Builder {
6072
self
6173
}
6274

63-
// TODO: Open-ended range
6475
pub fn limit(mut self, count: usize) -> Self {
65-
self.headers
66-
.push(("Content-Range".to_string(), format!("0-{}", count - 1)));
76+
self.headers.append(
77+
"Content-Range",
78+
HeaderValue::from_str(&format!("0-{}", count - 1)).unwrap(),
79+
);
80+
self
81+
}
82+
83+
pub fn range(mut self, low: usize, high: usize) -> Self {
84+
self.headers.append(
85+
"Content-Range",
86+
HeaderValue::from_str(&format!("{}-{}", low, high)).unwrap(),
87+
);
6788
self
6889
}
6990

7091
pub fn single(mut self) -> Self {
71-
self.headers.push((
72-
"Accept".to_string(),
73-
"application/vnd.pgrst.object+json".to_string(),
74-
));
92+
self.headers.insert(
93+
"Accept",
94+
HeaderValue::from_static("application/vnd.pgrst.object+json"),
95+
);
7596
self
7697
}
7798

@@ -81,34 +102,34 @@ impl Builder {
81102
pub fn insert(mut self, body: &str) -> Self {
82103
self.method = Method::POST;
83104
self.headers
84-
.push(("Prefer".to_string(), "return=representation".to_string()));
105+
.append("Prefer", HeaderValue::from_static("return=representation"));
85106
self.body = Some(body.to_string());
86107
self
87108
}
88109

89110
pub fn insert_csv(mut self, body: &str) -> Self {
90111
self.headers
91-
.push(("Content-Type".to_string(), "text/csv".to_string()));
112+
.append("Content-Type", HeaderValue::from_static("text/csv"));
92113
self.insert(body)
93114
}
94115

95116
// TODO: Allow Prefer: resolution=ignore-duplicates
96117
// TODO: on_conflict (make UPSERT work on UNIQUE columns)
97118
pub fn upsert(mut self, body: &str) -> Self {
98119
self.method = Method::POST;
99-
self.headers.push((
100-
"Prefer".to_string(),
120+
self.headers.append(
121+
"Prefer",
101122
// Maybe check if this works as intended...
102-
"return=representation; resolution=merge-duplicates".to_string(),
103-
));
123+
HeaderValue::from_static("return=representation; resolution=merge-duplicates"),
124+
);
104125
self.body = Some(body.to_string());
105126
self
106127
}
107128

108129
pub fn single_upsert(mut self, primary_column: &str, key: &str, body: &str) -> Self {
109130
self.method = Method::PUT;
110131
self.headers
111-
.push(("Prefer".to_string(), "return=representation".to_string()));
132+
.append("Prefer", HeaderValue::from_static("return=representation"));
112133
self.queries
113134
.push((primary_column.to_string(), format!("eq.{}", key)));
114135
self.body = Some(body.to_string());
@@ -118,15 +139,15 @@ impl Builder {
118139
pub fn update(mut self, body: &str) -> Self {
119140
self.method = Method::PATCH;
120141
self.headers
121-
.push(("Prefer".to_string(), "return=representation".to_string()));
142+
.append("Prefer", HeaderValue::from_static("return=representation"));
122143
self.body = Some(body.to_string());
123144
self
124145
}
125146

126147
pub fn delete(mut self) -> Self {
127148
self.method = Method::DELETE;
128149
self.headers
129-
.push(("Prefer".to_string(), "return=representation".to_string()));
150+
.append("Prefer", HeaderValue::from_static("return=representation"));
130151
self
131152
}
132153

@@ -150,7 +171,7 @@ impl Builder {
150171
self
151172
}
152173

153-
pub async fn execute(self) -> Result<Response, Error> {
174+
pub async fn execute(mut self) -> Result<Response, Error> {
154175
let mut req = Client::new().request(self.method.clone(), &self.url);
155176
if let Some(schema) = self.schema {
156177
// NOTE: Upstream bug: RPC only works with Accept-Profile
@@ -160,12 +181,10 @@ impl Builder {
160181
} else {
161182
"Content-Profile"
162183
};
163-
req = req.header(key, schema);
164-
}
165-
for (k, v) in &self.headers {
166-
req = req.header(k, v);
184+
self.headers
185+
.append(key, HeaderValue::from_str(&schema).unwrap());
167186
}
168-
req = req.query(&self.queries);
187+
req = req.headers(self.headers).query(&self.queries);
169188
if let Some(body) = self.body {
170189
req = req.body(body);
171190
}

0 commit comments

Comments
 (0)