parcelwing 0.1.0

Official Rust SDK for the Parcel Wing API.
Documentation
use std::sync::Arc;

use crate::error::Error;
use crate::http::HttpClient;
use crate::types::{
    segment_sort_by_to_string, sort_order_to_string, DeletionResponse, ListResponse,
    ResourceResponse, Segment, SegmentCreateRequest, SegmentListParams, SegmentUpdateRequest,
};

#[derive(Clone, Debug)]
pub struct SegmentsResource {
    http: Arc<HttpClient>,
}

impl SegmentsResource {
    pub(crate) fn new(http: Arc<HttpClient>) -> Self {
        Self { http }
    }

    pub async fn list(&self, params: SegmentListParams) -> Result<ListResponse<Segment>, Error> {
        self.http
            .get("/api/segments", Some(segment_query(params)))
            .await
    }

    pub async fn create(&self, input: SegmentCreateRequest) -> Result<Segment, Error> {
        let response: ResourceResponse<Segment> = self.http.post("/api/segments", &input).await?;
        Ok(response.data)
    }

    pub async fn get(&self, id: impl AsRef<str>) -> Result<Segment, Error> {
        let response: ResourceResponse<Segment> = self
            .http
            .get(&format!("/api/segments/{}", encode(id.as_ref())), None)
            .await?;
        Ok(response.data)
    }

    pub async fn update(
        &self,
        id: impl AsRef<str>,
        input: SegmentUpdateRequest,
    ) -> Result<Segment, Error> {
        let response: ResourceResponse<Segment> = self
            .http
            .patch(&format!("/api/segments/{}", encode(id.as_ref())), &input)
            .await?;
        Ok(response.data)
    }

    pub async fn delete(&self, id: impl AsRef<str>) -> Result<DeletionResponse, Error> {
        self.http
            .delete(&format!("/api/segments/{}", encode(id.as_ref())))
            .await
    }
}

fn segment_query(params: SegmentListParams) -> Vec<(&'static str, String)> {
    let mut query = Vec::new();
    if let Some(value) = params.page {
        query.push(("page", value.to_string()));
    }
    if let Some(value) = params.limit {
        query.push(("limit", value.to_string()));
    }
    if let Some(value) = params.search {
        query.push(("search", value));
    }
    if let Some(value) = params.active {
        query.push(("active", value.to_string()));
    }
    if let Some(value) = params.include_counts {
        query.push(("include_counts", value.to_string()));
    }
    if let Some(value) = params.sort_by {
        query.push(("sort_by", segment_sort_by_to_string(&value).to_string()));
    }
    if let Some(value) = params.sort_order {
        query.push(("sort_order", sort_order_to_string(&value).to_string()));
    }
    query
}

fn encode(value: &str) -> String {
    url::form_urlencoded::byte_serialize(value.as_bytes()).collect()
}