Skip to main content

lbc/models/
ad.rs

1use super::{LocationDetails, User};
2use crate::client::Client;
3use serde::Deserialize;
4
5#[derive(Debug, Clone, Deserialize)]
6pub struct Attribute {
7    pub key: Option<String>,
8    pub key_label: Option<String>,
9    pub value: Option<String>,
10    pub value_label: Option<String>,
11    pub values: Option<Vec<String>>,
12    pub values_label: Option<Vec<String>>,
13    pub value_label_reader: Option<String>,
14    pub generic: Option<bool>,
15}
16
17#[derive(Debug, Clone, Deserialize)]
18pub struct Ad {
19    #[serde(rename = "list_id")]
20    pub id: Option<u64>,
21    pub first_publication_date: Option<String>,
22    pub expiration_date: Option<String>,
23    pub index_date: Option<String>,
24    pub status: Option<String>,
25    pub category_id: Option<String>,
26    pub category_name: Option<String>,
27    pub subject: Option<String>,
28    pub body: Option<String>,
29    pub brand: Option<String>,
30    pub ad_type: Option<String>,
31    pub url: Option<String>,
32    #[serde(rename = "price_cents")]
33    price_cents: Option<u64>,
34    pub images: Option<AdImages>,
35    pub attributes: Option<Vec<Attribute>>,
36    pub location: Option<LocationDetails>,
37    pub has_phone: Option<bool>,
38    pub counters: Option<AdCounters>,
39    pub owner: Option<AdOwner>,
40
41    #[serde(skip)]
42    client: Option<Client>,
43}
44
45#[derive(Debug, Clone, Deserialize)]
46pub struct AdImages {
47    pub urls_large: Option<Vec<String>>,
48    pub urls_thumb: Option<Vec<String>>,
49}
50
51#[derive(Debug, Clone, Deserialize)]
52pub struct AdCounters {
53    pub favorites: Option<u64>,
54}
55
56#[derive(Debug, Clone, Deserialize)]
57pub struct AdOwner {
58    pub user_id: Option<String>,
59}
60
61impl Ad {
62    pub fn price(&self) -> Option<f64> {
63        self.price_cents.map(|cents| cents as f64 / 100.0)
64    }
65
66    pub fn title(&self) -> Option<&str> {
67        self.subject.as_deref()
68    }
69
70    pub fn favorites(&self) -> Option<u64> {
71        self.counters.as_ref().and_then(|c| c.favorites)
72    }
73
74    pub fn user_id(&self) -> Option<&str> {
75        self.owner.as_ref().and_then(|o| o.user_id.as_deref())
76    }
77
78    pub fn image_urls(&self) -> Vec<&str> {
79        self.images
80            .as_ref()
81            .and_then(|img| img.urls_large.as_ref())
82            .map(|urls| urls.iter().map(|s| s.as_str()).collect())
83            .unwrap_or_default()
84    }
85
86    /// Get user information for this ad (requires client)
87    pub async fn get_user(&self) -> crate::Result<Option<User>> {
88        match (&self.client, self.user_id()) {
89            (Some(client), Some(user_id)) => Ok(Some(client.get_user(user_id).await?)),
90            _ => Ok(None),
91        }
92    }
93
94    pub(crate) fn with_client(mut self, client: Client) -> Self {
95        self.client = Some(client);
96        self
97    }
98}