mirror of
https://github.com/asciinema/asciinema.git
synced 2025-12-15 19:28:00 +01:00
Use newtype for stream event ID
This commit is contained in:
30
src/alis.rs
30
src/alis.rs
@@ -196,7 +196,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let event = Event::Init(
|
let event = Event::Init(
|
||||||
42,
|
42.into(),
|
||||||
Duration::from_micros(1000),
|
Duration::from_micros(1000),
|
||||||
TtySize(180, 24),
|
TtySize(180, 24),
|
||||||
Some(theme),
|
Some(theme),
|
||||||
@@ -248,7 +248,7 @@ mod tests {
|
|||||||
let mut serializer = EventSerializer::default();
|
let mut serializer = EventSerializer::default();
|
||||||
|
|
||||||
let event = Event::Init(
|
let event = Event::Init(
|
||||||
1,
|
1.into(),
|
||||||
Duration::from_micros(500),
|
Duration::from_micros(500),
|
||||||
TtySize(120, 130),
|
TtySize(120, 130),
|
||||||
None,
|
None,
|
||||||
@@ -274,7 +274,11 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_serialize_output() {
|
fn test_serialize_output() {
|
||||||
let mut serializer = EventSerializer(Duration::from_micros(1000));
|
let mut serializer = EventSerializer(Duration::from_micros(1000));
|
||||||
let event = Event::Output(5, Duration::from_micros(1200), "Hello 世界 🌍".to_string());
|
let event = Event::Output(
|
||||||
|
5.into(),
|
||||||
|
Duration::from_micros(1200),
|
||||||
|
"Hello 世界 🌍".to_string(),
|
||||||
|
);
|
||||||
let bytes = serializer.serialize_event(event);
|
let bytes = serializer.serialize_event(event);
|
||||||
|
|
||||||
let mut expected = vec![
|
let mut expected = vec![
|
||||||
@@ -293,7 +297,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_serialize_input() {
|
fn test_serialize_input() {
|
||||||
let mut serializer = EventSerializer(Duration::from_micros(500));
|
let mut serializer = EventSerializer(Duration::from_micros(500));
|
||||||
let event = Event::Input(1000000, Duration::from_micros(750), "x".to_string());
|
let event = Event::Input(1000000.into(), Duration::from_micros(750), "x".to_string());
|
||||||
let bytes = serializer.serialize_event(event);
|
let bytes = serializer.serialize_event(event);
|
||||||
|
|
||||||
let expected = vec![
|
let expected = vec![
|
||||||
@@ -311,7 +315,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_serialize_resize() {
|
fn test_serialize_resize() {
|
||||||
let mut serializer = EventSerializer(Duration::from_micros(2000));
|
let mut serializer = EventSerializer(Duration::from_micros(2000));
|
||||||
let event = Event::Resize(15, Duration::from_micros(2100), TtySize(180, 50));
|
let event = Event::Resize(15.into(), Duration::from_micros(2100), TtySize(180, 50));
|
||||||
let bytes = serializer.serialize_event(event);
|
let bytes = serializer.serialize_event(event);
|
||||||
|
|
||||||
let expected = vec![
|
let expected = vec![
|
||||||
@@ -329,7 +333,11 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_serialize_marker_with_label() {
|
fn test_serialize_marker_with_label() {
|
||||||
let mut serializer = EventSerializer(Duration::from_micros(3000));
|
let mut serializer = EventSerializer(Duration::from_micros(3000));
|
||||||
let event = Event::Marker(20, Duration::from_micros(3500), "checkpoint".to_string());
|
let event = Event::Marker(
|
||||||
|
20.into(),
|
||||||
|
Duration::from_micros(3500),
|
||||||
|
"checkpoint".to_string(),
|
||||||
|
);
|
||||||
let bytes = serializer.serialize_event(event);
|
let bytes = serializer.serialize_event(event);
|
||||||
|
|
||||||
let expected = vec![
|
let expected = vec![
|
||||||
@@ -348,7 +356,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_serialize_marker_without_label() {
|
fn test_serialize_marker_without_label() {
|
||||||
let mut serializer = EventSerializer(Duration::from_micros(3000));
|
let mut serializer = EventSerializer(Duration::from_micros(3000));
|
||||||
let event = Event::Marker(2, Duration::from_micros(3300), "".to_string());
|
let event = Event::Marker(2.into(), Duration::from_micros(3300), "".to_string());
|
||||||
let bytes = serializer.serialize_event(event);
|
let bytes = serializer.serialize_event(event);
|
||||||
|
|
||||||
let expected = vec![
|
let expected = vec![
|
||||||
@@ -364,7 +372,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_serialize_exit_positive_status() {
|
fn test_serialize_exit_positive_status() {
|
||||||
let mut serializer = EventSerializer(Duration::from_micros(4000));
|
let mut serializer = EventSerializer(Duration::from_micros(4000));
|
||||||
let event = Event::Exit(25, Duration::from_micros(4200), 0);
|
let event = Event::Exit(25.into(), Duration::from_micros(4200), 0);
|
||||||
let bytes = serializer.serialize_event(event);
|
let bytes = serializer.serialize_event(event);
|
||||||
|
|
||||||
let expected = vec![
|
let expected = vec![
|
||||||
@@ -381,7 +389,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_serialize_exit_negative_status() {
|
fn test_serialize_exit_negative_status() {
|
||||||
let mut serializer = EventSerializer(Duration::from_micros(5000));
|
let mut serializer = EventSerializer(Duration::from_micros(5000));
|
||||||
let event = Event::Exit(30, Duration::from_micros(5300), -1);
|
let event = Event::Exit(30.into(), Duration::from_micros(5300), -1);
|
||||||
let bytes = serializer.serialize_event(event);
|
let bytes = serializer.serialize_event(event);
|
||||||
|
|
||||||
let expected = vec![
|
let expected = vec![
|
||||||
@@ -400,7 +408,7 @@ mod tests {
|
|||||||
let mut serializer = EventSerializer(Duration::from_micros(1000));
|
let mut serializer = EventSerializer(Duration::from_micros(1000));
|
||||||
|
|
||||||
// First event at time 1000
|
// First event at time 1000
|
||||||
let event1 = Event::Output(1, Duration::from_micros(1000), "first".to_string());
|
let event1 = Event::Output(1.into(), Duration::from_micros(1000), "first".to_string());
|
||||||
let bytes1 = serializer.serialize_event(event1);
|
let bytes1 = serializer.serialize_event(event1);
|
||||||
|
|
||||||
// Verify first event uses time 0 (1000 - 1000)
|
// Verify first event uses time 0 (1000 - 1000)
|
||||||
@@ -408,7 +416,7 @@ mod tests {
|
|||||||
assert_eq!(serializer.0.as_micros(), 1000);
|
assert_eq!(serializer.0.as_micros(), 1000);
|
||||||
|
|
||||||
// Second event with lower timestamp (wraparound risk case)
|
// Second event with lower timestamp (wraparound risk case)
|
||||||
let event2 = Event::Output(2, Duration::from_micros(500), "second".to_string());
|
let event2 = Event::Output(2.into(), Duration::from_micros(500), "second".to_string());
|
||||||
let bytes2 = serializer.serialize_event(event2);
|
let bytes2 = serializer.serialize_event(event2);
|
||||||
|
|
||||||
assert_eq!(bytes2[2], 0x00); // relative time should be 0
|
assert_eq!(bytes2[2], 0x00); // relative time should be 0
|
||||||
|
|||||||
@@ -25,14 +25,17 @@ struct Subscription {
|
|||||||
events_rx: broadcast::Receiver<Event>,
|
events_rx: broadcast::Receiver<Event>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct EventId(u64);
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
Init(u64, Duration, TtySize, Option<TtyTheme>, String),
|
Init(EventId, Duration, TtySize, Option<TtyTheme>, String),
|
||||||
Output(u64, Duration, String),
|
Output(EventId, Duration, String),
|
||||||
Input(u64, Duration, String),
|
Input(EventId, Duration, String),
|
||||||
Resize(u64, Duration, TtySize),
|
Resize(EventId, Duration, TtySize),
|
||||||
Marker(u64, Duration, String),
|
Marker(EventId, Duration, String),
|
||||||
Exit(u64, Duration, i32),
|
Exit(EventId, Duration, i32),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -78,7 +81,7 @@ async fn run(
|
|||||||
let (broadcast_tx, _) = broadcast::channel(1024);
|
let (broadcast_tx, _) = broadcast::channel(1024);
|
||||||
let mut vt = build_vt(tty_size);
|
let mut vt = build_vt(tty_size);
|
||||||
let mut stream_time = Duration::from_micros(0);
|
let mut stream_time = Duration::from_micros(0);
|
||||||
let mut last_event_id = 0;
|
let mut last_event_id = EventId::new(0);
|
||||||
let mut last_event_time = Instant::now();
|
let mut last_event_time = Instant::now();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
@@ -87,7 +90,7 @@ async fn run(
|
|||||||
match event {
|
match event {
|
||||||
Some(event) => {
|
Some(event) => {
|
||||||
last_event_time = Instant::now();
|
last_event_time = Instant::now();
|
||||||
last_event_id += 1;
|
last_event_id = last_event_id.next();
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
session::Event::Output(time, text) => {
|
session::Event::Output(time, text) => {
|
||||||
@@ -126,7 +129,7 @@ async fn run(
|
|||||||
request = request_rx.recv() => {
|
request = request_rx.recv() => {
|
||||||
match request {
|
match request {
|
||||||
Some(request) => {
|
Some(request) => {
|
||||||
let init = if last_event_id > 0 {
|
let init = if last_event_id.as_u64() > 0 {
|
||||||
let elapsed_time = stream_time + last_event_time.elapsed();
|
let elapsed_time = stream_time + last_event_time.elapsed();
|
||||||
|
|
||||||
Event::Init(
|
Event::Init(
|
||||||
@@ -158,6 +161,32 @@ async fn run(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EventId {
|
||||||
|
fn new(id: u64) -> Self {
|
||||||
|
EventId(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next(&self) -> Self {
|
||||||
|
EventId(self.0 + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_u64(&self) -> u64 {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<EventId> for u64 {
|
||||||
|
fn from(id: EventId) -> Self {
|
||||||
|
id.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u64> for EventId {
|
||||||
|
fn from(id: u64) -> Self {
|
||||||
|
EventId(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Subscriber {
|
impl Subscriber {
|
||||||
pub async fn subscribe(
|
pub async fn subscribe(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
Reference in New Issue
Block a user