use serde::{Deserialize, Serialize};
use crate::{
api::{Method, Payload, PayloadError},
types::{LabeledPrice, User},
};
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
pub struct ShippingAddress {
pub city: String,
pub country_code: String,
pub post_code: String,
pub state: String,
pub street_line1: String,
pub street_line2: String,
}
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
pub struct ShippingOption {
id: String,
title: String,
prices: Vec<LabeledPrice>,
}
impl ShippingOption {
pub fn new<A, B, C>(id: A, title: B, prices: C) -> Self
where
A: Into<String>,
B: Into<String>,
C: IntoIterator<Item = LabeledPrice>,
{
Self {
id: id.into(),
title: title.into(),
prices: prices.into_iter().collect(),
}
}
pub fn id(&self) -> &str {
&self.id
}
pub fn title(&self) -> &str {
&self.title
}
pub fn prices(&self) -> &[LabeledPrice] {
&self.prices
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
pub struct ShippingQuery {
pub id: String,
pub from: User,
pub invoice_payload: String,
pub shipping_address: ShippingAddress,
}
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, Serialize)]
pub struct AnswerShippingQuery {
ok: bool,
shipping_query_id: String,
error_message: Option<String>,
shipping_options: Option<Vec<ShippingOption>>,
}
impl AnswerShippingQuery {
pub fn ok<A, B>(id: A, options: B) -> Self
where
A: Into<String>,
B: IntoIterator<Item = ShippingOption>,
{
Self {
ok: true,
shipping_query_id: id.into(),
error_message: None,
shipping_options: Some(options.into_iter().collect()),
}
}
pub fn error<A, B>(id: A, message: B) -> Self
where
A: Into<String>,
B: Into<String>,
{
Self {
ok: false,
shipping_query_id: id.into(),
error_message: Some(message.into()),
shipping_options: None,
}
}
}
impl Method for AnswerShippingQuery {
type Response = bool;
fn into_payload(self) -> Result<Payload, PayloadError> {
Payload::json("answerShippingQuery", self)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn shipping_option() {
let obj = ShippingOption::new("id", "title", [LabeledPrice::new(10, "label")]);
assert_eq!(obj.id(), "id");
assert_eq!(obj.title(), "title");
assert_eq!(obj.prices().len(), 1);
}
}