use std::future::{Future, IntoFuture};
use serde::Serialize;
use typed_builder::TypedBuilder;
use crate::{error::ZarinResult, results::verify::Verify, ZarinpalClient};
use super::ApiMethod;
#[derive(Debug, Clone, Serialize, TypedBuilder)]
pub struct VerifyPayment<'z, Z: ZarinpalClient> {
#[builder(default, setter(strip_option, into))]
merchant_id: Option<String>,
amount: u64,
#[builder(setter(into))]
authority: String,
#[serde(skip_serializing)]
#[builder(setter(strip_option))]
zarinpal: Option<&'z Z>,
}
impl<'z, Z: ZarinpalClient + Sync + Send> IntoFuture for VerifyPayment<'z, Z> {
type Output = ZarinResult<Verify>;
type IntoFuture = ::core::pin::Pin<Box<dyn Future<Output = Self::Output> + Send + 'z>>;
fn into_future(mut self) -> Self::IntoFuture {
let zarinpal = std::mem::take(&mut self.zarinpal).unwrap(); Box::pin(zarinpal.send(self))
}
}
impl<'z, Z: ZarinpalClient> ApiMethod for VerifyPayment<'z, Z> {
const PATH: &'static str = "pg/v4/payment/verify.json";
type Result = Verify;
fn set_merchant_id_if_needed(&mut self, merchant_id: impl Into<String>) {
match self.merchant_id {
None => self.merchant_id = Some(merchant_id.into()),
_ => (),
}
}
}
#[cfg(test)]
mod tests {
use crate::Zarinpal;
use super::*;
#[test]
fn test_serialization() {
let zarinpal = Zarinpal::new_test().unwrap();
let raw_json = serde_json::json!({
"merchant_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"amount": 1000,
"authority": "A00000000000000000000000000217885159"
});
let from_model = serde_json::to_value(
&VerifyPayment::builder()
.merchant_id("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
.amount(1000)
.authority("A00000000000000000000000000217885159")
.zarinpal(&zarinpal)
.build(),
)
.unwrap();
assert_eq!(raw_json, from_model)
}
use std::future::Future;
use std::pin::Pin;
struct MyFuture<'a, T>(&'a T);
impl<'a, T: Sync> IntoFuture for MyFuture<'a, T> {
type Output = ();
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>;
fn into_future(self) -> Self::IntoFuture {
Box::pin(async move {
let _t = self.0;
()
})
}
}
}