Skip to content

Commit

Permalink
Merge pull request #9 from primait/v2
Browse files Browse the repository at this point in the history
Astrazione del body della request
  • Loading branch information
matteosister authored Oct 26, 2020
2 parents 6ef2143 + 833c173 commit c20096f
Show file tree
Hide file tree
Showing 17 changed files with 912 additions and 86 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,7 @@ tokio-test = { version = "0.2", optional = true }
opentelemetry = { version = "0.8.0", optional = true }
tracing = { version = "0.1.19", optional = true }
tracing-opentelemetry = { version = "0.7.0", optional = true }
async-trait = "0.1.41"

[dev-dependencies]
mockito = "0.25.2"
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,32 @@
# bridge.rs
Prima bridge pattern implementation for rust

### Example


This is a WORK IN PROGRESS
```rust
use prima_bridge::prelude::*;
use serde::Deserialize;

#[derive(Deserialize)]
struct DeserializableData {
test: String
}

// using we make sure that `Bridge` get instantiated only once
fn bridge() -> &'static Bridge {
static BRIDGE: OnceCell<Bridge> = OnceCell::new();
BRIDGE.get_or_init(|| Bridge::new("https://prima.it/api"))
}

// Do not use expect in production! It will cause runtime errors. Use Result.
pub fn fetch_data() -> YourResult<DeserializableData> {
Request::get(bridge())
.send()?
.get_data(&["nested", "selector"])? // response is {"nested": {"selector": {"data": "test"}}}
}
```

To understand this example you should know:
- [once_cell](https://crates.io/crates/once_cell) library providing the cell type
- Rust error handling to use ? and convert it to a custom error type. See for example [thiserror](https://crates.io/crates/thiserror)
7 changes: 7 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use reqwest::{StatusCode, Url};
use serde_json::Value;
use std::convert::Infallible;
use thiserror::Error;

pub type PrimaBridgeResult<T> = Result<T, PrimaBridgeError>;
Expand All @@ -22,3 +23,9 @@ pub enum PrimaBridgeError {
#[error("empty body")]
EmptyBody,
}

impl From<Infallible> for PrimaBridgeError {
fn from(_: Infallible) -> Self {
unimplemented!()
}
}
15 changes: 9 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@ mod errors;
pub mod prelude;
mod request;
mod response;
mod v2;

pub use self::{
request::{Request, RequestType},
response::Response,
};
pub use self::{response::Response, v2::GraphQLRequest, v2::Request};
use crate::request::{Request as OldRequest, RequestType};
use reqwest::Url;
use serde::Serialize;

Expand All @@ -49,7 +48,11 @@ impl Bridge {
}
}

pub fn request<S: Serialize>(&self, request_type: RequestType<S>) -> Request<S> {
Request::new(&self, request_type)
#[deprecated(
since = "0.2.0",
note = "Use the RestRequest and GraphQLRequest ::new constructor instead of this function"
)]
pub fn request<S: Serialize>(&self, request_type: RequestType<S>) -> OldRequest<S> {
OldRequest::new(&self, request_type)
}
}
1 change: 1 addition & 0 deletions src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ pub use super::errors::*;
pub use super::{
request::{GraphQL, RequestType, Rest},
response::Response,
v2::{DeliverableRequest, GraphQLRequest, Request, RestRequest},
Bridge,
};
22 changes: 21 additions & 1 deletion src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ impl<'a, S: Serialize> Request<'a, S> {
let mut additional_headers = vec![];
additional_headers.append(&mut self.custom_headers().to_vec());
additional_headers.append(&mut self.tracing_headers().to_vec());
dbg!(&additional_headers);
let request_builder = additional_headers
.iter()
.fold(request_builder, |request, (name, value)| {
Expand Down Expand Up @@ -304,6 +303,27 @@ pub struct GraphQLBody<T> {
variables: Option<T>,
}

impl<T: Serialize> From<(&str, Option<T>)> for GraphQLBody<T> {
fn from((query, variables): (&str, Option<T>)) -> Self {
Self {
query: query.to_owned(),
variables,
}
}
}

impl<T: Serialize> From<(String, Option<T>)> for GraphQLBody<T> {
fn from((query, variables): (String, Option<T>)) -> Self {
(query.as_str(), variables).into()
}
}

impl<T: Serialize> From<(String, T)> for GraphQLBody<T> {
fn from((query, variables): (String, T)) -> Self {
(query.as_str(), Some(variables)).into()
}
}

#[derive(Debug)]
pub struct Rest<S: Serialize> {
request_id: Uuid,
Expand Down
7 changes: 7 additions & 0 deletions src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub struct Response {
}

impl Response {
#[doc(hidden)]
pub fn rest(
url: Url,
response_body: String,
Expand All @@ -42,6 +43,7 @@ impl Response {
}
}

#[doc(hidden)]
pub fn graphql(
url: Url,
response_body: String,
Expand All @@ -59,13 +61,17 @@ impl Response {
}
}

#[doc(hidden)]
fn is_graphql(&self) -> bool {
self.request_type == RequestType::GraphQL
}

/// Returns an `HeaderMap` of response headers.
pub fn headers(&self) -> &HeaderMap {
&self.response_headers
}

/// Returns data from the function.
pub fn get_data<T>(self, response_extractor: &[&str]) -> PrimaBridgeResult<T>
where
for<'de> T: Deserialize<'de> + Debug,
Expand All @@ -83,6 +89,7 @@ impl Response {
Ok(extract_inner_json(self.url, selectors, json_value)?)
}

/// returns `true` if the response is successful
pub fn is_ok(&self) -> bool {
self.status_code.is_success()
}
Expand Down
38 changes: 38 additions & 0 deletions src/v2/body.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#[derive(Clone, Debug)]
pub struct Body {
inner: Vec<u8>,
}

impl Default for Body {
fn default() -> Self {
Self { inner: vec![] }
}
}

impl From<String> for Body {
fn from(val: String) -> Self {
Self {
inner: val.into_bytes(),
}
}
}

impl From<&str> for Body {
fn from(val: &str) -> Self {
Self {
inner: val.to_string().into_bytes(),
}
}
}

impl From<Vec<u8>> for Body {
fn from(value: Vec<u8>) -> Self {
Self { inner: value }
}
}

impl From<Body> for Vec<u8> {
fn from(body: Body) -> Self {
body.inner
}
}
Loading

0 comments on commit c20096f

Please sign in to comment.