Skip to content

Commit

Permalink
remove boxed errors, some updates
Browse files Browse the repository at this point in the history
  • Loading branch information
edg-l committed Jan 8, 2021
1 parent 5ba9bfa commit 5f77a90
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 101 deletions.
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "paypal-rs"
version = "0.2.0-alpha.2"
version = "0.2.0-alpha.3"
authors = ["Edgar <[email protected]>"]
description = "A library that wraps the paypal api asynchronously."
repository = "https://github.com/edg-l/paypal-rs/"
Expand All @@ -23,6 +23,5 @@ log = "0.4.11"
bytes = "1.0.0"

[dev-dependencies]
# Can't update this until reqwest updates.
tokio = { version = "1.0.1", features = ["macros", "rt"] }
dotenv = "0.15.0"
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# paypal-rs
[![Crates.io](https://meritbadge.herokuapp.com/paypal-rs)](https://crates.io/crates/paypal-rs)
![Rust](https://github.com/edg-l/paypal-rs/workflows/Rust/badge.svg)
![Docs](https://docs.rs/paypal-rs/badge.svg)
[![Docs](https://docs.rs/paypal-rs/badge.svg)](https://docs.rs/paypal-rs)

A rust library that wraps the [paypal api](https://developer.paypal.com/docs/api) asynchronously in a stringly typed manner.

Expand Down Expand Up @@ -35,9 +35,7 @@ async fn main() {

let order_payload = OrderPayload::new(
Intent::Authorize,
vec![PurchaseUnit::new(Amount::new(
Currency::EUR, "10.0",
))],
vec![PurchaseUnit::new(Amount::new(Currency::EUR, "10.0"))],
);

let order = client
Expand Down
16 changes: 13 additions & 3 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ use std::collections::HashMap;
use std::error::Error;
use std::fmt;


/// A paypal api response error.
#[derive(Debug, Serialize, Deserialize)]
pub struct ApiResponseError {
pub struct PaypalError {
/// The error name.
pub name: String,
/// The error message.
Expand All @@ -24,13 +25,22 @@ pub struct ApiResponseError {
pub links: Vec<LinkDescription>,
}

impl fmt::Display for ApiResponseError {
impl fmt::Display for PaypalError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:#?}", self)
}
}

impl Error for ApiResponseError {}
impl Error for PaypalError {}

/// A response error, it may be paypal related or an error related to the http request itself.
#[derive(Debug)]
pub enum ResponseError {
/// A paypal api error.
ApiError(PaypalError),
/// A http error.
HttpError(reqwest::Error)
}

/// When a currency is invalid.
#[derive(Debug)]
Expand Down
103 changes: 52 additions & 51 deletions src/invoice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
//! Reference: https://developer.paypal.com/docs/api/invoicing/v2/
use crate::common::*;
use crate::errors;
use crate::HeaderParams;
use crate::errors::{ResponseError, PaypalError};
use bytes::Bytes;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
Expand Down Expand Up @@ -727,7 +728,7 @@ impl super::Client {
pub async fn generate_invoice_number(
&mut self,
header_params: crate::HeaderParams,
) -> Result<String, Box<dyn std::error::Error>> {
) -> Result<String, ResponseError> {
let build = self
.setup_headers(
self.client
Expand All @@ -736,13 +737,13 @@ impl super::Client {
)
.await;

let res = build.send().await?;
let res = build.send().await.map_err(ResponseError::HttpError)?;

if res.status().is_success() {
let x = res.json::<HashMap<String, String>>().await?;
let x = res.json::<HashMap<String, String>>().await.map_err(ResponseError::HttpError)?;
Ok(x.get("invoice_number").expect("to have a invoice number").clone())
} else {
Err(Box::new(res.json::<errors::ApiResponseError>().await?))
Err(ResponseError::ApiError(res.json::<PaypalError>().await.map_err(ResponseError::HttpError)?))
}
}

Expand All @@ -751,8 +752,8 @@ impl super::Client {
pub async fn create_draft_invoice(
&mut self,
invoice: InvoicePayload,
header_params: crate::HeaderParams,
) -> Result<Invoice, Box<dyn std::error::Error>> {
header_params: HeaderParams,
) -> Result<Invoice, ResponseError> {
let build = self
.setup_headers(
self.client
Expand All @@ -761,22 +762,22 @@ impl super::Client {
)
.await;

let res = build.json(&invoice).send().await?;
let res = build.json(&invoice).send().await.map_err(ResponseError::HttpError)?;

if res.status().is_success() {
let x = res.json::<Invoice>().await?;
let x = res.json::<Invoice>().await.map_err(ResponseError::HttpError)?;
Ok(x)
} else {
Err(Box::new(res.json::<errors::ApiResponseError>().await?))
Err(ResponseError::ApiError(res.json::<PaypalError>().await.map_err(ResponseError::HttpError)?))
}
}

/// Get an invoice by ID.
pub async fn get_invoice<S: std::fmt::Display>(
pub async fn get_invoice(
&mut self,
invoice_id: S,
header_params: crate::HeaderParams,
) -> Result<Invoice, Box<dyn std::error::Error>> {
invoice_id: &str,
header_params: HeaderParams,
) -> Result<Invoice, ResponseError> {
let build = self
.setup_headers(
self.client
Expand All @@ -785,13 +786,13 @@ impl super::Client {
)
.await;

let res = build.send().await?;
let res = build.send().await.map_err(ResponseError::HttpError)?;

if res.status().is_success() {
let x = res.json::<Invoice>().await?;
let x = res.json::<Invoice>().await.map_err(ResponseError::HttpError)?;
Ok(x)
} else {
Err(Box::new(res.json::<errors::ApiResponseError>().await?))
Err(ResponseError::ApiError(res.json::<PaypalError>().await.map_err(ResponseError::HttpError)?))
}
}

Expand All @@ -801,8 +802,8 @@ impl super::Client {
&mut self,
page: i32,
page_size: i32,
header_params: crate::HeaderParams,
) -> Result<InvoiceList, Box<dyn std::error::Error>> {
header_params: HeaderParams,
) -> Result<InvoiceList, ResponseError> {
let build = self
.setup_headers(
self.client.get(
Expand All @@ -818,22 +819,22 @@ impl super::Client {
)
.await;

let res = build.send().await?;
let res = build.send().await.map_err(ResponseError::HttpError)?;

if res.status().is_success() {
let x = res.json::<InvoiceList>().await?;
let x = res.json::<InvoiceList>().await.map_err(ResponseError::HttpError)?;
Ok(x)
} else {
Err(Box::new(res.json::<errors::ApiResponseError>().await?))
Err(ResponseError::ApiError(res.json::<PaypalError>().await.map_err(ResponseError::HttpError)?))
}
}

/// Delete a invoice
pub async fn delete_invoice<S: std::fmt::Display>(
pub async fn delete_invoice(
&mut self,
invoice_id: S,
header_params: crate::HeaderParams,
) -> Result<(), Box<dyn std::error::Error>> {
invoice_id: &str,
header_params: HeaderParams,
) -> Result<(), ResponseError> {
let build = self
.setup_headers(
self.client
Expand All @@ -842,12 +843,12 @@ impl super::Client {
)
.await;

let res = build.send().await?;
let res = build.send().await.map_err(ResponseError::HttpError)?;

if res.status().is_success() {
Ok(())
} else {
Err(Box::new(res.json::<errors::ApiResponseError>().await?))
Err(ResponseError::ApiError(res.json::<PaypalError>().await.map_err(ResponseError::HttpError)?))
}
}

Expand All @@ -857,8 +858,8 @@ impl super::Client {
invoice: Invoice,
send_to_recipient: bool,
send_to_invoicer: bool,
header_params: crate::HeaderParams,
) -> Result<(), Box<dyn std::error::Error>> {
header_params: HeaderParams,
) -> Result<(), ResponseError> {
let build = self
.setup_headers(
self.client.put(
Expand All @@ -875,22 +876,22 @@ impl super::Client {
)
.await;

let res = build.send().await?;
let res = build.send().await.map_err(ResponseError::HttpError)?;

if res.status().is_success() {
Ok(())
} else {
Err(Box::new(res.json::<errors::ApiResponseError>().await?))
Err(ResponseError::ApiError(res.json::<PaypalError>().await.map_err(ResponseError::HttpError)?))
}
}

/// Cancel a invoice
pub async fn cancel_invoice<S: std::fmt::Display>(
pub async fn cancel_invoice(
&mut self,
invoice_id: S,
invoice_id: &str,
reason: CancelReason,
header_params: crate::HeaderParams,
) -> Result<(), Box<dyn std::error::Error>> {
header_params: HeaderParams,
) -> Result<(), ResponseError> {
let build = self
.setup_headers(
self.client
Expand All @@ -899,22 +900,22 @@ impl super::Client {
)
.await;

let res = build.json(&reason).send().await?;
let res = build.json(&reason).send().await.map_err(ResponseError::HttpError)?;

if res.status().is_success() {
Ok(())
} else {
Err(Box::new(res.json::<errors::ApiResponseError>().await?))
Err(ResponseError::ApiError(res.json::<PaypalError>().await.map_err(ResponseError::HttpError)?))
}
}

/// Generate a QR code
pub async fn generate_qr_code<S: std::fmt::Display>(
pub async fn generate_qr_code(
&mut self,
invoice_id: S,
invoice_id: &str,
params: QRCodeParams,
header_params: crate::HeaderParams,
) -> Result<Bytes, Box<dyn std::error::Error>> {
header_params: HeaderParams,
) -> Result<Bytes, ResponseError> {
let build = self
.setup_headers(
self.client.post(
Expand All @@ -929,23 +930,23 @@ impl super::Client {
)
.await;

let res = build.json(&params).send().await?;
let res = build.json(&params).send().await.map_err(ResponseError::HttpError)?;

if res.status().is_success() {
let b = res.bytes().await?;
let b = res.bytes().await.map_err(ResponseError::HttpError)?;
Ok(b)
} else {
Err(Box::new(res.json::<errors::ApiResponseError>().await?))
Err(ResponseError::ApiError(res.json::<PaypalError>().await.map_err(ResponseError::HttpError)?))
}
}

/// Records a payment for the invoice. If no payment is due, the invoice is marked as PAID. Otherwise, the invoice is marked as PARTIALLY PAID.
pub async fn record_invoice_payment<S: std::fmt::Display>(
pub async fn record_invoice_payment(
&mut self,
invoice_id: S,
invoice_id: &str,
payload: RecordPaymentPayload,
header_params: crate::HeaderParams,
) -> Result<String, Box<dyn std::error::Error>> {
) -> Result<String, ResponseError> {
let build = self
.setup_headers(
self.client
Expand All @@ -954,13 +955,13 @@ impl super::Client {
)
.await;

let res = build.json(&payload).send().await?;
let res = build.json(&payload).send().await.map_err(ResponseError::HttpError)?;

if res.status().is_success() {
let x = res.json::<HashMap<String, String>>().await?;
let x = res.json::<HashMap<String, String>>().await.map_err(ResponseError::HttpError)?;
Ok(x.get("payment_id").unwrap().to_owned())
} else {
Err(Box::new(res.json::<errors::ApiResponseError>().await?))
Err(ResponseError::ApiError(res.json::<PaypalError>().await.map_err(ResponseError::HttpError)?))
}
}

Expand Down
Loading

0 comments on commit 5f77a90

Please sign in to comment.