lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README | LICENSE

listing.rs (5758B)


      1 use radroots_core::{
      2     RadrootsCoreDecimal, RadrootsCoreDiscount, RadrootsCoreMoney, RadrootsCoreQuantity,
      3     RadrootsCoreQuantityPrice, RadrootsCoreUnit,
      4 };
      5 
      6 use crate::farm::RadrootsFarmRef;
      7 use crate::ids::{RadrootsDTag, RadrootsInventoryBinId};
      8 use crate::plot::RadrootsPlotRef;
      9 use crate::resource_area::RadrootsResourceAreaRef;
     10 
     11 #[cfg(not(feature = "std"))]
     12 use alloc::{string::String, vec::Vec};
     13 
     14 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
     15 #[cfg_attr(
     16     feature = "serde",
     17     serde(rename_all = "snake_case", tag = "kind", content = "amount")
     18 )]
     19 #[derive(Clone, Debug)]
     20 pub enum RadrootsListingAvailability {
     21     Window {
     22         start: Option<u64>,
     23         end: Option<u64>,
     24     },
     25     Status {
     26         status: RadrootsListingStatus,
     27     },
     28 }
     29 
     30 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
     31 #[cfg_attr(
     32     feature = "serde",
     33     serde(rename_all = "snake_case", tag = "kind", content = "amount")
     34 )]
     35 #[derive(Clone, Debug)]
     36 pub enum RadrootsListingStatus {
     37     Active,
     38     Sold,
     39     Other { value: String },
     40 }
     41 
     42 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
     43 #[cfg_attr(
     44     feature = "serde",
     45     serde(rename_all = "snake_case", tag = "kind", content = "amount")
     46 )]
     47 #[derive(Clone, Debug)]
     48 pub enum RadrootsListingDeliveryMethod {
     49     Pickup,
     50     LocalDelivery,
     51     Shipping,
     52     Other { method: String },
     53 }
     54 
     55 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
     56 #[derive(Clone, Debug)]
     57 pub struct RadrootsListing {
     58     pub d_tag: RadrootsDTag,
     59     #[cfg_attr(
     60         feature = "serde",
     61         serde(default, skip_serializing_if = "Option::is_none")
     62     )]
     63     pub published_at: Option<u64>,
     64     #[cfg_attr(feature = "serde", serde(default))]
     65     pub farm: RadrootsFarmRef,
     66     pub product: RadrootsListingProduct,
     67     pub primary_bin_id: RadrootsInventoryBinId,
     68     pub bins: Vec<RadrootsListingBin>,
     69     pub resource_area: Option<RadrootsResourceAreaRef>,
     70     pub plot: Option<RadrootsPlotRef>,
     71     pub discounts: Option<Vec<RadrootsCoreDiscount>>,
     72     pub inventory_available: Option<RadrootsCoreDecimal>,
     73     pub availability: Option<RadrootsListingAvailability>,
     74     pub delivery_method: Option<RadrootsListingDeliveryMethod>,
     75     pub location: Option<RadrootsListingLocation>,
     76     pub images: Option<Vec<RadrootsListingImage>>,
     77 }
     78 
     79 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
     80 #[derive(Clone, Debug)]
     81 pub struct RadrootsListingProduct {
     82     pub key: String,
     83     pub title: String,
     84     pub category: String,
     85     pub summary: Option<String>,
     86     pub process: Option<String>,
     87     pub lot: Option<String>,
     88     pub location: Option<String>,
     89     pub profile: Option<String>,
     90     pub year: Option<String>,
     91 }
     92 
     93 pub const RADROOTS_LISTING_PRODUCT_TAG_KEYS: [&str; 9] = [
     94     "key", "title", "category", "summary", "process", "lot", "location", "profile", "year",
     95 ];
     96 
     97 pub struct RadrootsListingProductTagKeys;
     98 
     99 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
    100 #[derive(Clone, Debug)]
    101 pub struct RadrootsListingBin {
    102     pub bin_id: RadrootsInventoryBinId,
    103     pub quantity: RadrootsCoreQuantity,
    104     pub price_per_canonical_unit: RadrootsCoreQuantityPrice,
    105     pub display_amount: Option<RadrootsCoreDecimal>,
    106     pub display_unit: Option<RadrootsCoreUnit>,
    107     pub display_label: Option<String>,
    108     pub display_price: Option<RadrootsCoreMoney>,
    109     pub display_price_unit: Option<RadrootsCoreUnit>,
    110 }
    111 
    112 #[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))]
    113 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
    114 #[derive(Clone, Debug)]
    115 pub struct RadrootsListingLocation {
    116     pub primary: String,
    117     pub city: Option<String>,
    118     pub region: Option<String>,
    119     pub country: Option<String>,
    120     pub lat: Option<f64>,
    121     pub lng: Option<f64>,
    122     pub geohash: Option<String>,
    123 }
    124 
    125 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
    126 #[derive(Clone, Debug)]
    127 pub struct RadrootsListingImage {
    128     pub url: String,
    129     pub size: Option<RadrootsListingImageSize>,
    130 }
    131 
    132 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
    133 #[derive(Clone, Debug)]
    134 pub struct RadrootsListingImageSize {
    135     pub w: u32,
    136     pub h: u32,
    137 }
    138 
    139 #[cfg(all(test, feature = "std"))]
    140 mod tests {
    141     use crate::farm::RadrootsFarmRef;
    142 
    143     #[test]
    144     fn defaults_listing_farm_ref_to_empty_values() {
    145         let farm_ref = RadrootsFarmRef::default();
    146         assert!(farm_ref.pubkey.is_empty());
    147         assert!(farm_ref.d_tag.is_empty());
    148     }
    149 
    150     #[test]
    151     fn listing_model_covers_published_draft_metadata() {
    152         use crate::kinds::{KIND_LISTING_DRAFT, is_listing_kind};
    153 
    154         let listing = super::RadrootsListing {
    155             d_tag: "listing-draft".parse().unwrap(),
    156             published_at: Some(1_700_000_000),
    157             farm: RadrootsFarmRef::default(),
    158             product: super::RadrootsListingProduct {
    159                 key: "lettuce".to_string(),
    160                 title: "lettuce".to_string(),
    161                 category: "produce".to_string(),
    162                 summary: None,
    163                 process: None,
    164                 lot: None,
    165                 location: None,
    166                 profile: None,
    167                 year: None,
    168             },
    169             primary_bin_id: "bin-1".parse().unwrap(),
    170             bins: vec![],
    171             resource_area: None,
    172             plot: None,
    173             discounts: None,
    174             inventory_available: None,
    175             availability: None,
    176             delivery_method: None,
    177             location: None,
    178             images: None,
    179         };
    180 
    181         assert_eq!(listing.published_at, Some(1_700_000_000));
    182         assert!(is_listing_kind(KIND_LISTING_DRAFT));
    183     }
    184 }