real_stripe_client.rs

 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}