init
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
//! Product data adapters. The deal source is a user-pasted product URL — no
|
||||
//! per-retailer scrapers. Adapters are generic platform readers; the first is
|
||||
//! Shopify, whose storefronts expose a public `/products/{handle}.json` document.
|
||||
|
||||
use rust_decimal::Decimal;
|
||||
|
||||
mod shopify;
|
||||
|
||||
/// Normalised product snapshot produced by an adapter.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FetchedProduct {
|
||||
pub title: String,
|
||||
pub price: Decimal,
|
||||
pub currency: String,
|
||||
pub image_url: Option<String>,
|
||||
pub in_stock: Option<bool>,
|
||||
pub source: &'static str,
|
||||
}
|
||||
|
||||
/// A shared HTTP client tuned for storefront fetches.
|
||||
pub fn http_client() -> reqwest::Client {
|
||||
reqwest::Client::builder()
|
||||
.user_agent("consumers-bot/0.1 (+self-hosted wantlist price watcher)")
|
||||
.timeout(std::time::Duration::from_secs(15))
|
||||
.build()
|
||||
.expect("failed to build reqwest client")
|
||||
}
|
||||
|
||||
/// Try every adapter in turn. Returns the first that recognises the URL.
|
||||
pub async fn fetch_product(
|
||||
client: &reqwest::Client,
|
||||
url: &str,
|
||||
default_currency: &str,
|
||||
) -> anyhow::Result<FetchedProduct> {
|
||||
if let Some(p) = shopify::fetch(client, url, default_currency).await? {
|
||||
return Ok(p);
|
||||
}
|
||||
anyhow::bail!("no adapter could read this URL (only Shopify storefronts are supported for now)")
|
||||
}
|
||||
Reference in New Issue
Block a user