use std::{fmt, str};
use serde::{Deserialize, Serialize};
use serde_repr::*;
use chrono::{DateTime, Utc};
use super::OTAPackageVersion;
#[derive(Debug, Serialize_repr, Deserialize_repr, Clone)]
#[repr(u8)]
pub enum OTADeviceType {
Cellular,
Bluetooth,
}
impl fmt::Display for OTADeviceType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let text = match self {
OTADeviceType::Cellular => "cellular",
OTADeviceType::Bluetooth => "bluetooth",
};
write!(f, "{}", text)
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct OTAPackageFileInfo {
pub image_type: OTAImageType,
pub host: String,
pub file: String,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct OTAPackage {
pub version: OTAPackageVersion,
pub files: Vec<OTAPackageFileInfo>,
pub date_added: Option<DateTime<Utc>>,
}
impl fmt::Display for OTAPackage {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.version,)
}
}
impl From<OTAPackage> for Option<super::v1::OTAPackage> {
fn from(pkg: OTAPackage) -> Self {
let image = pkg
.files
.iter()
.find(|x| x.image_type == OTAImageType::Primary);
match image {
Some(i) => Some(super::v1::OTAPackage {
version: pkg.version.clone(),
host: i.host.clone(),
file: i.file.clone(),
force: false,
}),
None => None,
}
}
}
#[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug, Clone, Copy)]
#[repr(u8)]
pub enum OTAImageType {
Primary = 1 << 0,
Secondary = 1 << 1,
}
impl fmt::Display for OTAImageType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let string = match self {
OTAImageType::Primary => "primary",
OTAImageType::Secondary => "secondary",
};
write!(f, "{}", string)
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct OTAImageData {
pub data: Vec<u8>,
pub image_type: OTAImageType,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct OtaUpdate {
#[serde(skip_serializing_if = "Option::is_none")]
pub uid: Option<String>,
pub package: Option<OTAPackage>,
#[serde(skip_serializing_if = "Option::is_none")]
pub images: Option<Vec<OTAImageData>>,
}