use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Delta {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub context: Option<String>,
#[serde(default)]
pub updates: Vec<Update>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Update {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub timestamp: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub source: Option<Value>,
#[serde(default)]
pub values: Vec<PathValue>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PathValue {
pub path: String,
pub value: Value,
}
impl Delta {
#[must_use]
pub fn single(context: Option<String>, path: &str, value: Value) -> Self {
Self {
context,
updates: vec![Update {
timestamp: None,
source: None,
values: vec![PathValue {
path: path.to_owned(),
value,
}],
}],
}
}
}
const AIS_PGNS: [u64; 11] = [
129_038, 129_039, 129_040, 129_041, 129_793, 129_794, 129_798, 129_801, 129_802, 129_809,
129_810,
];
impl Update {
#[must_use]
pub fn is_own_sensor(&self) -> bool {
let Some(source) = &self.source else {
return false;
};
if let Some(sentence) = source.get("sentence").and_then(Value::as_str) {
return sentence != "VDM";
}
source
.get("pgn")
.and_then(Value::as_u64)
.is_some_and(|pgn| !AIS_PGNS.contains(&pgn))
}
}