ek-event 0.1.0

Self-contained event engine in Rust, a faithful semantic replication of enkeep_trade's event engine. No dependency on enkeep_trade.
Documentation
//! P8 —— 批量事件模式:eTickStockBatch 等,data 为 list,handler 内逐条消费。

use ek_event::{Event, EventEngine};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Arc, Mutex};
use std::time::Duration;

fn wait_for(cond: impl Fn() -> bool) -> bool {
    for _ in 0..300 {
        if cond() {
            return true;
        }
        std::thread::sleep(Duration::from_millis(10));
    }
    cond()
}

#[derive(Clone, Debug)]
#[allow(dead_code)] // 仅 symbol 被断言读取,price 用于构造贴近真实 tick
struct TickMsg {
    symbol: String,
    price: f64,
}

// B1: 500 条批量 tick,list 载荷全收 + 顺序保持(复刻 _process_tick_event 的 list 分支)
#[test]
fn b1_batch_list_payload() {
    let engine = Arc::new(EventEngine::new());
    engine.start();

    let events_seen = Arc::new(AtomicUsize::new(0));
    let rows = Arc::new(Mutex::new(Vec::<(String, usize)>::new()));

    let r = rows.clone();
    let ev = events_seen.clone();
    engine.register("eTickStockBatch", Arc::new(move |e| {
        ev.fetch_add(1, Ordering::SeqCst);
        let batch = e.data.downcast_ref::<Vec<TickMsg>>().expect("Vec<TickMsg> payload");
        for (i, t) in batch.iter().enumerate() {
            r.lock().unwrap().push((t.symbol.clone(), i));
        }
    }));

    const N: usize = 500;
    let batch: Vec<TickMsg> = (0..N)
        .map(|i| TickMsg { symbol: format!("S{i:04}"), price: i as f64 })
        .collect();
    engine
        .put(Event::with_data("eTickStockBatch", Arc::new(batch)))
        .unwrap();

    assert!(wait_for(|| events_seen.load(Ordering::SeqCst) == 1), "batch event delivered");
    assert!(wait_for(|| rows.lock().unwrap().len() == N), "all 500 rows consumed");
    let got = rows.lock().unwrap().clone();
    let idx_ok = got.iter().enumerate().all(|(k, (_, i))| k == *i);
    assert!(idx_ok, "batch iteration order must match the list order");
    assert_eq!(got[0].0, "S0000");
    assert_eq!(got[N - 1].0, "S0499");
    engine.stop();
}