samling 0.13.1

App for managing apparel collections
Documentation
use futures::future::try_join4;

use crate::{I18nString, Id, ItemFilterChoices, Organization, RefType, Result};
use samling_clorinde::{
    client::GenericClient,
    queries::admin::{
        select_attribute_filter_choices, select_category_filter_choices,
        select_status_filter_choices, select_style_filter_choices, EntityFilterChoiceRow,
        StringFilterChoiceRowBorrowed,
    },
};

use super::{EntityFilterChoice, StringFilterChoice};

#[derive(Clone)]
pub struct FiltersRepo;

impl FiltersRepo {
    pub async fn list_item_filters(
        &self,
        client: &impl GenericClient,
        organization_id: Id<Organization>,
    ) -> Result<ItemFilterChoices> {
        let mut status_query = select_status_filter_choices();
        let mut category_query = select_category_filter_choices();
        let mut style_query = select_style_filter_choices();
        let mut attribute_query = select_attribute_filter_choices();
        let status_future = status_query
            .bind(client, organization_id.inner())
            .map(|row| row.into())
            .all();
        let category_future = category_query.bind(client, organization_id.inner()).all();
        let style_future = style_query.bind(client, organization_id.inner()).all();
        let attribute_future = attribute_query.bind(client, organization_id.inner()).all();
        let (status, category_res, style_res, attribute_res) = try_join4(
            status_future,
            category_future,
            style_future,
            attribute_future,
        )
        .await?;
        let category = category_res
            .into_iter()
            .map(TryInto::try_into)
            .collect::<Result<Vec<_>>>()?;
        let style = style_res
            .into_iter()
            .map(TryInto::try_into)
            .collect::<Result<Vec<_>>>()?;
        let attribute = attribute_res
            .into_iter()
            .map(TryInto::try_into)
            .collect::<Result<Vec<_>>>()?;
        Ok(ItemFilterChoices {
            status,
            category,
            style,
            attribute,
        })
    }
}

impl<'a> From<StringFilterChoiceRowBorrowed<'a>> for StringFilterChoice {
    fn from(row: StringFilterChoiceRowBorrowed<'a>) -> Self {
        row.title.to_owned().into()
    }
}

impl TryFrom<EntityFilterChoiceRow> for EntityFilterChoice {
    type Error = crate::Error;
    fn try_from(row: EntityFilterChoiceRow) -> Result<Self> {
        let title: I18nString = serde_path_to_error::deserialize(row.title)?;
        let subtitle = row
            .subtitle
            .map_or_else(|| Ok(None), serde_path_to_error::deserialize)?;
        let image = row
            .image
            .map_or_else(|| Ok(None), serde_path_to_error::deserialize)?;
        Ok(Self {
            id: row.id,
            title,
            subtitle,
            image,
        })
    }
}