use serde::{Deserialize, Serialize};
use std::{collections::HashMap, fmt::Display};
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ShortenResponse {
pub short_url: String,
}
#[derive(Debug, Serialize, Default, Clone)]
pub struct ShortenRequest {
pub(crate) url: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) alias: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) password: Option<String>,
#[serde(rename = "max-clicks", skip_serializing_if = "Option::is_none")]
pub(crate) max_clicks: Option<u32>,
#[serde(rename = "block-bots", skip_serializing_if = "Option::is_none")]
pub(crate) block_bots: Option<bool>,
}
impl ShortenRequest {
pub fn new<U: Into<String>>(url: U) -> Self {
ShortenRequest {
url: url.into(),
..Default::default()
}
}
pub fn alias<A: Into<String>>(mut self, alias: A) -> Self {
self.alias = Some(alias.into());
self
}
pub fn password<P: Into<String>>(mut self, password: P) -> Self {
self.password = Some(password.into());
self
}
pub fn max_clicks(mut self, max: u32) -> Self {
self.max_clicks = Some(max);
self
}
pub fn block_bots(mut self, flag: bool) -> Self {
self.block_bots = Some(flag);
self
}
}
#[derive(Debug, Serialize, Default, Clone)]
pub struct EmojiRequest {
pub(crate) url: String,
#[serde(rename = "emojies", skip_serializing_if = "Option::is_none")]
pub(crate) emojies: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) password: Option<String>,
#[serde(rename = "max-clicks", skip_serializing_if = "Option::is_none")]
pub(crate) max_clicks: Option<u32>,
#[serde(rename = "block-bots", skip_serializing_if = "Option::is_none")]
pub(crate) block_bots: Option<bool>,
}
impl EmojiRequest {
pub fn new<U: Into<String>>(url: U) -> Self {
EmojiRequest {
url: url.into(),
..Default::default()
}
}
pub fn emojies<E: Into<String>>(mut self, seq: E) -> Self {
self.emojies = Some(seq.into());
self
}
pub fn password<P: Into<String>>(mut self, password: P) -> Self {
self.password = Some(password.into());
self
}
pub fn max_clicks(mut self, max: u32) -> Self {
self.max_clicks = Some(max);
self
}
pub fn block_bots(mut self, flag: bool) -> Self {
self.block_bots = Some(flag);
self
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct EmojiResponse {
pub short_url: String,
}
#[derive(Debug, Serialize, Default, Clone)]
pub struct StatsRequest {
#[serde(skip_serializing)]
pub(crate) short_code: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) password: Option<String>,
}
impl StatsRequest {
pub fn new(short_code: &str) -> Self {
StatsRequest {
short_code: short_code.to_string(),
password: None,
}
}
pub fn password<P: Into<String>>(mut self, password: P) -> Self {
self.password = Some(password.into());
self
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct StatsResponse {
pub short_code: String,
pub url: String,
#[serde(rename = "total-clicks")]
pub total_clicks: u32,
pub total_unique_clicks: u32,
#[serde(rename = "creation-date")]
pub creation_date: Option<String>,
pub expired: Option<bool>,
#[serde(rename = "last-click")]
pub last_click: Option<String>,
#[serde(rename = "last-click-browser")]
pub last_click_browser: Option<String>,
#[serde(rename = "last-click-os")]
pub last_click_os: Option<String>,
#[serde(rename = "max-clicks")]
pub max_clicks: Option<u32>,
pub password: Option<String>,
pub block_bots: Option<bool>,
pub bots: Option<HashMap<String, u32>>,
pub browser: Option<HashMap<String, u32>>,
pub country: Option<HashMap<String, u32>>,
pub counter: Option<HashMap<String, u32>>,
pub unique_browser: Option<HashMap<String, u32>>,
pub unique_country: Option<HashMap<String, u32>>,
pub unique_counter: Option<HashMap<String, u32>>,
pub unique_os_name: Option<HashMap<String, u32>>,
pub unique_referrer: Option<HashMap<String, u32>>,
}
#[derive(Debug, Deserialize, Clone)]
pub enum ExportFormat {
JSON,
CSV,
XLSX,
XML,
}
impl Display for ExportFormat {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ExportFormat::JSON => write!(f, "json"),
ExportFormat::CSV => write!(f, "csv"),
ExportFormat::XLSX => write!(f, "xlsx"),
ExportFormat::XML => write!(f, "xml"),
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ExportRequest {
#[serde(skip_serializing)]
pub(crate) short_code: String,
#[serde(skip_serializing)]
pub(crate) export_format: ExportFormat,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) password: Option<String>,
}
impl ExportRequest {
pub fn new<S: Into<String>>(short_code: S, export_format: ExportFormat) -> Self {
ExportRequest {
short_code: short_code.into(),
export_format,
password: None,
}
}
pub fn password<P: Into<String>>(mut self, password: P) -> Self {
self.password = Some(password.into());
self
}
}
#[derive(Debug, Clone)]
pub struct ExportResponse {
pub(crate) data: Vec<u8>,
}
impl ExportResponse {
pub fn save_to_file(&self, path: &str) -> std::io::Result<()> {
use std::fs::File;
use std::io::Write;
let mut file = File::create(path)?;
file.write_all(&self.data)?;
Ok(())
}
pub fn data(&self) -> &[u8] {
&self.data
}
}