Skip to main content

navi_vm/
events.rs

1use std::sync::Arc;
2
3pub use navi_types::BarStartEvent;
4use navi_types::Warnings;
5use navi_visuals::ChartEvent;
6use num_enum::FromPrimitive;
7use serde::{Deserialize, Serialize};
8
9use crate::{DrawEvent, SymbolInfo, script_info::ScriptInfo, strategy::StrategyEvent};
10
11/// Logging severity used by [`LogEvent`].
12#[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, Serialize, Deserialize)]
13#[repr(i32)]
14#[serde(rename_all = "camelCase")]
15pub enum LogLevel {
16    /// Informational message.
17    #[default]
18    Info,
19    /// Warning condition.
20    Warning,
21    /// Error condition.
22    Error,
23}
24
25/// A log event emitted by script execution.
26#[derive(Debug, Clone, Serialize, Deserialize)]
27#[serde(rename_all = "camelCase")]
28pub struct LogEvent {
29    /// Severity level.
30    pub level: LogLevel,
31    /// Human-readable message.
32    pub message: String,
33}
34
35/// An alert event emitted by `alert()`/alertcondition-like behavior.
36#[derive(Debug, Clone, Serialize, Deserialize)]
37#[serde(rename_all = "camelCase")]
38pub struct AlertEvent {
39    /// Optional alert identifier.
40    pub id: Option<usize>,
41    /// Alert message.
42    pub message: String,
43}
44
45/// An event generated during VM execution.
46///
47/// Events are yielded by the [`Stream`](futures_util::Stream) returned from
48/// [`Instance::run`](crate::Instance::run).
49///
50/// Variants are grouped into three semantic categories, reflecting when they
51/// are emitted:
52///
53/// **Stream-level metadata** (emitted outside of bars, at most once per
54/// stream): [`SessionInfo`](Self::SessionInfo), [`Warning`](Self::Warning).
55///
56/// **Bar boundaries** (mark the start/end of execution phases):
57/// [`BarStart`](Self::BarStart), [`BarEnd`](Self::BarEnd),
58/// [`HistoryEnd`](Self::HistoryEnd).
59///
60/// **Per-bar data** (always appear between a `BarStart`/`BarEnd` pair):
61/// [`Draw`](Self::Draw), [`Strategy`](Self::Strategy),
62/// [`Log`](Self::Log), [`Alert`](Self::Alert).
63#[derive(Debug, Clone, Serialize, Deserialize)]
64#[serde(rename_all = "camelCase")]
65pub enum Event {
66    /// Session metadata emitted first in the stream, before any bar
67    /// (only in [`OutputMode::Stream`](crate::OutputMode::Stream)).
68    ///
69    /// Carries both the script declaration ([`ScriptInfo`]) and the symbol
70    /// metadata ([`SymbolInfo`]) for the current run.
71    SessionInfo {
72        /// Script-level metadata (type, declared inputs, series, alerts).
73        script_info: Arc<ScriptInfo>,
74        /// Symbol metadata for the chart symbol being analyzed.
75        symbol_info: Box<SymbolInfo>,
76    },
77    /// Compilation warnings, emitted after `ScriptInfo` and before any bar
78    /// (only when warnings are present).
79    Warning(Warnings),
80    /// Signals the start of a bar's execution.
81    BarStart(BarStartEvent),
82    /// Signals the end of a bar's execution.
83    BarEnd,
84    /// Signals the boundary between historical and real-time bars
85    /// (only in [`OutputMode::Stream`](crate::OutputMode::Stream)).
86    HistoryEnd,
87    /// A drawing instruction (only in
88    /// [`OutputMode::Stream`](crate::OutputMode::Stream)).
89    Draw(DrawEvent),
90    /// A strategy event (only in
91    /// [`OutputMode::Stream`](crate::OutputMode::Stream)).
92    Strategy(StrategyEvent),
93    /// A log message emitted by `log.*()` calls.
94    Log(LogEvent),
95    /// An alert emitted by `alert()`.
96    Alert(AlertEvent),
97}
98
99impl TryFrom<Event> for ChartEvent {
100    /// Returns the original `Event` when conversion is not possible.
101    type Error = Event;
102
103    fn try_from(event: Event) -> Result<ChartEvent, Event> {
104        match event {
105            Event::SessionInfo {
106                script_info,
107                symbol_info,
108            } => Ok(ChartEvent::SessionInfo {
109                script_info,
110                symbol_info,
111            }),
112            Event::HistoryEnd => Ok(ChartEvent::HistoryEnd),
113            Event::Draw(draw) => Ok(ChartEvent::from(draw)),
114            other => Err(other),
115        }
116    }
117}