yepzon-locationer/thingy_lib/src/api/structs.rs

261 lines
7.1 KiB
Rust

use super::{Config, LibError};
use serde::Deserialize;
use std::fmt::{Display, Formatter};
pub trait Timestamped {
fn timestamp(&self) -> Option<String>;
}
#[derive(Deserialize, Debug)]
pub struct ErrorModel {
#[serde(rename(deserialize = "Message"))]
pub message: Option<String>,
}
#[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct SharetokenModel {
token: Option<String>,
url: Option<String>,
expires: Option<String>,
}
impl Timestamped for SharetokenModel {
fn timestamp(&self) -> Option<String> {
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<String>,
pub imei: Option<String>,
pub battery_value: Option<i32>,
pub bt_id: Option<String>,
pub nfc_id: Option<String>,
pub pair_code: Option<String>,
pub location: Option<LocationModel>,
pub state: Option<ChangingState>,
pub last_contact: Option<String>,
pub charging: Option<bool>,
pub charger_connected: Option<bool>,
pub config: Option<ChangingConfig>,
pub capabilities: Option<Capabilities>,
}
impl TagModel {
pub fn get_nick(&self, config: &Config) -> Option<String> {
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<String, LibError> {
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<i32>,
pub sleep_interval: Option<i32>,
pub sos_alert_sound_enabled: Option<bool>,
pub mode: Option<String>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct ChangingConfig {
current: Option<ConfigModel>,
pending: Option<ConfigModel>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct Capabilities {
rx: Option<bool>,
sos: Option<bool>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub struct StateModel {
pub id: Option<String>,
pub timestamp: Option<String>,
pub state: Option<String>,
pub real_state: Option<String>,
}
impl StateModel {
pub fn get_id(&self) -> Result<String, LibError> {
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<String> {
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<StateModel>,
pending: Option<StateModel>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct LocationModel {
pub timestamp: Option<String>,
#[serde(rename(deserialize = "type"))]
pub loc_type: Option<String>,
#[serde(rename(deserialize = "coordinateLat"))]
#[serde(alias = "latitude")]
pub lat: Option<f64>,
#[serde(rename(deserialize = "coordinateLng"))]
#[serde(alias = "longitude")]
pub lon: Option<f64>,
pub accuracy: Option<f32>,
}
impl Timestamped for LocationModel {
fn timestamp(&self) -> Option<String> {
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)
}
}