use super::{Config, LibError}; use serde::Deserialize; use std::fmt::{Display, Formatter}; pub trait Timestamped { fn timestamp(&self) -> Option; } #[derive(Deserialize, Debug)] pub struct ErrorModel { #[serde(rename(deserialize = "Message"))] pub message: Option, } #[derive(Deserialize, Debug)] #[serde(deny_unknown_fields)] pub struct SharetokenModel { token: Option, url: Option, expires: Option, } impl Timestamped for SharetokenModel { fn timestamp(&self) -> Option { self.expires.clone() } } impl Display for SharetokenModel { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { let mut text = String::new(); text += &format!( " token = {}", self.token.as_ref().unwrap_or(&"unknown".to_owned()) ); text += &format!( "\n url = {}", self.url.as_ref().unwrap_or(&"unknown".to_owned()) ); text += &format!( "\n expiry time = {}", &self.expires.as_ref().unwrap_or(&"unknown".to_owned()) ); write!(f, "{}", text) } } #[derive(Deserialize, Debug, Clone)] #[serde(deny_unknown_fields)] #[serde(rename_all = "camelCase")] pub struct TagModel { pub id: Option, pub imei: Option, pub battery_value: Option, pub bt_id: Option, pub nfc_id: Option, pub pair_code: Option, pub location: Option, pub state: Option, pub last_contact: Option, pub charging: Option, pub charger_connected: Option, pub config: Option, pub capabilities: Option, } impl TagModel { pub fn get_nick(&self, config: &Config) -> Option { if let Some(id) = &self.id { if let Some(n) = config.nicknames.get(id) { Some(n.clone()) } else { None } } else { None } } pub fn get_id(&self) -> Result { match &self.id { Some(id) => Ok(id.to_string()), None => Err(LibError::MessagedError( "Could not find device id. Error probably on Yetzon server side.".to_owned(), None, )), } } } impl Display for TagModel { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { let mut text = String::new(); text += &format!( " id = {}", self.id.as_ref().unwrap_or(&"unknown".to_owned()) ); text += &format!( "\n imei = {}", self.imei.as_ref().unwrap_or(&"unknown".to_owned()) ); text += &format!( "\n battery value = {}%", &self .battery_value .map(|v| v.to_string()) .unwrap_or("unknown".to_owned()) ); text += &format!( "\n bluetooth id = {}", &self.bt_id.as_ref().unwrap_or(&"unknown".to_owned()) ); text += &format!( "\n NFC id = {}", &self.nfc_id.as_ref().unwrap_or(&"unknown".to_owned()) ); write!(f, "{}", text) } } #[derive(Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] #[serde(deny_unknown_fields)] pub struct ConfigModel { pub active_interval: Option, pub sleep_interval: Option, pub sos_alert_sound_enabled: Option, pub mode: Option, } #[derive(Deserialize, Debug, Clone)] #[serde(deny_unknown_fields)] pub struct ChangingConfig { current: Option, pending: Option, } #[derive(Deserialize, Debug, Clone)] #[serde(deny_unknown_fields)] pub struct Capabilities { rx: Option, sos: Option, } #[derive(Deserialize, Debug, Clone)] #[serde(deny_unknown_fields)] #[serde(rename_all = "camelCase")] pub struct StateModel { pub id: Option, pub timestamp: Option, pub state: Option, pub real_state: Option, } impl StateModel { pub fn get_id(&self) -> Result { match &self.id { Some(id) => Ok(id.to_string()), None => Err(LibError::MessagedError( "Could not find state id. Error probably on Yetzon server side.".to_owned(), None, )), } } } impl Timestamped for StateModel { fn timestamp(&self) -> Option { self.timestamp.clone() } } impl Display for StateModel { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { let mut text = String::new(); text += &format!( " id = {}", self.id.as_ref().unwrap_or(&"unknown".to_owned()) ); text += &format!( "\n timestamp = {}", self.timestamp.as_ref().unwrap_or(&"unknown".to_owned()) ); text += &format!( "\n state = {}", self.state.as_ref().unwrap_or(&"unknown".to_owned()) ); text += &format!( "\n real state = {}", self.real_state .as_ref() .unwrap_or(&"no real state".to_owned()) ); write!(f, "{}", text) } } #[derive(Deserialize, Debug, Clone)] #[serde(deny_unknown_fields)] pub struct ChangingState { current: Option, pending: Option, } #[derive(Deserialize, Debug, Clone)] #[serde(deny_unknown_fields)] pub struct LocationModel { pub timestamp: Option, #[serde(rename(deserialize = "type"))] pub loc_type: Option, #[serde(rename(deserialize = "coordinateLat"))] #[serde(alias = "latitude")] pub lat: Option, #[serde(rename(deserialize = "coordinateLng"))] #[serde(alias = "longitude")] pub lon: Option, pub accuracy: Option, } impl Timestamped for LocationModel { fn timestamp(&self) -> Option { self.timestamp.clone() } } impl Display for LocationModel { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { let mut text = String::new(); text += &format!( " timestamp = {}", self.timestamp().as_ref().unwrap_or(&"unknown".to_owned()) ); text += &format!( "\n location type = {}", self.loc_type.as_ref().unwrap_or(&"unknown".to_owned()) ); text += &format!( "\n latitude = {}", self.lat .as_ref() .map(|v| v.to_string()) .unwrap_or("unknown".to_owned()) ); text += &format!( "\n longitude = {}", self.lon .as_ref() .map(|v| v.to_string()) .unwrap_or("unknown".to_owned()) ); text += &format!( "\n accuracy = {}", self.accuracy .as_ref() .map(|v| v.to_string()) .unwrap_or("unknown".to_owned()) ); write!(f, "{}", text) } }