1use std::str::FromStr as _;
2use std::sync::Arc;
3
4use anyhow::{Context as _, Result};
5use async_trait::async_trait;
6use stripe::{CreateCustomer, Customer, CustomerId, ListCustomers};
7
8use crate::stripe_client::{CreateCustomerParams, StripeClient, StripeCustomer, StripeCustomerId};
9
10pub struct RealStripeClient {
11 client: Arc<stripe::Client>,
12}
13
14impl RealStripeClient {
15 pub fn new(client: Arc<stripe::Client>) -> Self {
16 Self { client }
17 }
18}
19
20#[async_trait]
21impl StripeClient for RealStripeClient {
22 async fn list_customers_by_email(&self, email: &str) -> Result<Vec<StripeCustomer>> {
23 let response = Customer::list(
24 &self.client,
25 &ListCustomers {
26 email: Some(email),
27 ..Default::default()
28 },
29 )
30 .await?;
31
32 Ok(response
33 .data
34 .into_iter()
35 .map(StripeCustomer::from)
36 .collect())
37 }
38
39 async fn create_customer(&self, params: CreateCustomerParams<'_>) -> Result<StripeCustomer> {
40 let customer = Customer::create(
41 &self.client,
42 CreateCustomer {
43 email: params.email,
44 ..Default::default()
45 },
46 )
47 .await?;
48
49 Ok(StripeCustomer::from(customer))
50 }
51}
52
53impl From<CustomerId> for StripeCustomerId {
54 fn from(value: CustomerId) -> Self {
55 Self(value.as_str().into())
56 }
57}
58
59impl TryFrom<StripeCustomerId> for CustomerId {
60 type Error = anyhow::Error;
61
62 fn try_from(value: StripeCustomerId) -> Result<Self, Self::Error> {
63 Self::from_str(value.0.as_ref()).context("failed to parse Stripe customer ID")
64 }
65}
66
67impl From<Customer> for StripeCustomer {
68 fn from(value: Customer) -> Self {
69 StripeCustomer {
70 id: value.id.into(),
71 email: value.email,
72 }
73 }
74}