verity_client/request.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
use std::convert::TryFrom;
use http::{HeaderName, HeaderValue};
use reqwest::{header::HeaderMap, Body, Request};
use serde::Serialize;
use crate::client::{VerityClient, VerityResponse};
/// A builder to construct the properties of a `Request`.
///
/// To construct a `RequestBuilder`, refer to the `Client` documentation.
#[must_use = "RequestBuilder does nothing until you 'send' it"]
pub struct RequestBuilder {
pub(crate) client: VerityClient,
pub(crate) inner: reqwest::RequestBuilder,
}
impl RequestBuilder {
/// Add a `Header` to this Request.
///
/// This method allows you to add a single header to the request.
pub fn header<K, V>(self, key: K, value: V) -> Self
where
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: Into<http::Error>,
HeaderValue: TryFrom<V>,
<HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
{
RequestBuilder {
inner: self.inner.header(key, value),
..self
}
}
/// Add a set of Headers to the existing ones on this Request.
///
/// This method merges the provided headers with any already set on the request.
pub fn headers(self, headers: HeaderMap) -> Self {
RequestBuilder {
inner: self.inner.headers(headers),
..self
}
}
/// Set the request body.
///
/// This method sets the body of the request to the provided value.
pub fn body<T: Into<Body>>(self, body: T) -> Self {
RequestBuilder {
inner: self.inner.body(body),
..self
}
}
/// Send a JSON body.
///
/// This method serializes the provided data structure as JSON and sets it as the request body.
///
/// # Errors
///
/// Serialization can fail if `T`'s implementation of `Serialize` decides to
/// fail, or if `T` contains a map with non-string keys.
pub fn json<T: Serialize + ?Sized>(self, json: &T) -> Self {
RequestBuilder {
inner: self.inner.json(json),
..self
}
}
/// Add a Redact instruction.
///
/// This method adds a header to instruct Verity Prover on how to hide sensitive data.
pub fn redact(self, redact: String) -> Self {
RequestBuilder {
inner: self
.inner
.header("T-REDACTED", HeaderValue::from_str(&redact).unwrap()),
..self
}
}
/// Build a `Request`.
///
/// This method constructs the request, which can then be
/// inspected, modified and executed with `VerityClient::execute()`.
pub fn build(self) -> reqwest::Result<Request> {
self.inner.build()
}
/// Build a `Request`, which can be inspected, modified and executed with
/// `VerityClient::execute()`.
///
/// This is similar to [`RequestBuilder::build()`], but also returns the
/// embedded `VerityClient`.
pub fn build_split(self) -> (VerityClient, reqwest::Result<Request>) {
let Self { inner, client, .. } = self;
let (_, req) = inner.build_split();
(client, req)
}
/// Constructs the Request and sends it to the target URL, returning a
/// future Response.
///
/// # Errors
///
/// This method fails if there was an error while sending request,
/// redirect loop was detected or redirect limit was exhausted.
///
/// # Example
///
/// ```no_run
/// # use anyhow::Error;
/// # use verity_client::client::{VerityClient, VerityClientConfig};
/// # async fn run() -> Result<(), Error> {
///
///
/// let config = VerityClientConfig {
/// prover_url: String::from("http://127.0.0.1:8080"),
/// };
///
/// let response = VerityClient::new(config)
/// .get("https://hyper.rs")
/// .send()
/// .await?;
/// # Ok(())
/// # }
/// ```
pub async fn send(self) -> anyhow::Result<VerityResponse> {
let (mut client, req) = self.build_split();
client.execute_request(req?).await
}
}