use serde::Deserialize;
use serde_json::Value;
use crate::{Error, events::EventTail};
#[derive(Debug, Clone)]
pub struct WatchRecord {
pub seq: Option<u64>,
pub raw: Value,
pub event: Option<Box<basis::Event>>,
}
pub struct EventCursor {
tail: EventTail,
}
impl EventCursor {
pub(crate) fn new(tail: EventTail) -> Self {
Self { tail }
}
pub fn poll(&mut self) -> Result<Vec<WatchRecord>, Error> {
let records = self
.tail
.poll()
.map_err(|error| Error::new(format!("read task events: {error}")))?;
Ok(records.into_iter().map(build_record).collect())
}
}
fn build_record(raw: Value) -> WatchRecord {
let seq = raw.get("seq").and_then(Value::as_u64);
let event = basis::Event::deserialize(&raw).ok().map(Box::new);
WatchRecord { seq, raw, event }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_record_with_a_numeric_seq_carries_it() {
let record = build_record(serde_json::json!({"seq": 3, "type": "notice", "message": "hi"}));
assert_eq!(record.seq, Some(3));
}
#[test]
fn a_record_with_no_seq_is_none_not_zero() {
let record = build_record(serde_json::json!({"type": "notice", "message": "hi"}));
assert_eq!(record.seq, None);
let not_a_number = build_record(serde_json::json!({"seq": "not-a-number"}));
assert_eq!(not_a_number.seq, None);
}
}