use std::sync::atomic::{AtomicU64, Ordering};
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
use serde_with::DisplayFromStr;
pub mod aiot_module;
pub mod alink_topic;
#[derive(Debug, Clone, Default)]
pub struct ThreeTuple {
pub product_key: String,
pub device_name: String,
pub device_secret: String,
}
impl ThreeTuple {
pub fn from_env() -> Self {
Self {
product_key: std::env::var("PRODUCT_KEY").unwrap(),
device_name: std::env::var("DEVICE_NAME").unwrap(),
device_secret: std::env::var("DEVICE_SECRET").unwrap(),
}
}
}
static ID: AtomicU64 = AtomicU64::new(1);
pub fn global_id_next() -> u64 {
ID.fetch_add(1, Ordering::SeqCst)
}
#[serde_as]
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct SimpleResponse {
pub id: String,
#[serde_as(as = "_")]
pub code: u64,
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ParamsRequest<T> {
pub id: String,
pub params: T,
}
impl<T> ParamsRequest<T> {
pub fn new(params: T) -> Self {
Self {
id: global_id_next().to_string(),
params,
}
}
}
#[serde_as]
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct AlinkResponse<T = Option<()>, TID = String, TCode = u64> {
pub id: TID,
pub code: TCode,
pub data: T,
pub message: Option<String>,
pub method: Option<String>,
pub version: Option<String>,
}
impl<T> AlinkResponse<T> {
pub fn msg_id(&self) -> u64 {
self.id.parse().unwrap_or(0)
}
pub fn new(id: u64, code: u64, data: T) -> Self {
Self {
id: format!("{}", id),
code,
data,
message: None,
version: None,
method: None,
}
}
}
pub const ALINK_VERSION: &str = "1.0";
#[serde_as]
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct AlinkRequest<T = Option<()>> {
pub id: String,
pub version: String,
pub params: T,
#[serde(skip_serializing_if = "Option::is_none")]
pub sys: Option<SysAck>,
#[serde(skip_serializing_if = "Option::is_none")]
pub method: Option<String>,
}
impl<T> AlinkRequest<T> {
pub fn msg_id(&self) -> u64 {
self.id.parse().unwrap_or(0)
}
pub fn new_id(id: u64, method: &str, params: T, ack: Option<i32>) -> Self {
Self {
id: format!("{}", id),
version: ALINK_VERSION.to_string(),
params,
sys: ack.map(|ack| SysAck { ack }),
method: Some(method.to_string()),
}
}
pub fn from_params(params: T) -> Self {
Self {
id: global_id_next().to_string(),
version: ALINK_VERSION.to_string(),
params,
sys: None,
method: None,
}
}
pub fn new(method: &str, params: T, ack: i32) -> Self {
Self::new_id(global_id_next(), method, params, Some(ack))
}
pub fn new_no_ack(method: &str, params: T) -> Self {
Self::new_id(global_id_next(), method, params, None)
}
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct SysAck {
pub ack: i32,
}