flowsurface_data/chart/kline/indicators/core/
output.rs1use crate::chart::kline::IndicatorInstanceId;
2use indicator_engine::{OutputPrecision, ReadoutBehavior};
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6pub enum OutputValueType {
7 Number,
8 Boolean,
9 Ohlc,
10 Range,
11}
12
13#[derive(Debug, Clone, PartialEq)]
15pub struct OutputChannelSpec {
16 pub id: String,
17 pub label: String,
18 pub value_type: OutputValueType,
19 pub precision: OutputPrecision,
20 pub line_width: f32,
21 pub readout: ReadoutBehavior,
22 pub style_slot: Option<String>,
23 pub offset_bars: i32,
24 pub style_by: Option<String>,
25 pub independent_scale: bool,
26}
27
28#[derive(Debug, Clone, Copy, PartialEq)]
30pub enum OutputValue {
31 Number(f64),
32 Boolean(bool),
33}
34
35impl OutputValue {
36 pub const fn value_type(self) -> OutputValueType {
37 match self {
38 Self::Number(_) => OutputValueType::Number,
39 Self::Boolean(_) => OutputValueType::Boolean,
40 }
41 }
42
43 pub fn as_f64(self) -> f64 {
44 match self {
45 Self::Number(value) => value,
46 Self::Boolean(value) => f64::from(value),
47 }
48 }
49
50 pub fn as_number(self) -> Option<f64> {
51 match self {
52 Self::Number(value) => value.is_finite().then_some(value),
53 Self::Boolean(_) => None,
54 }
55 }
56
57 pub fn as_boolean(self) -> Option<bool> {
58 match self {
59 Self::Boolean(value) => Some(value),
60 Self::Number(_) => None,
61 }
62 }
63}
64
65#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
67pub struct IndicatorOutputRef {
68 pub instance_id: IndicatorInstanceId,
69 pub channel_id: String,
70}
71
72impl IndicatorOutputRef {
73 pub fn new(instance_id: IndicatorInstanceId, channel_id: impl Into<String>) -> Self {
74 Self {
75 instance_id,
76 channel_id: channel_id.into(),
77 }
78 }
79
80 pub fn is_valid(&self) -> bool {
81 !self.channel_id.trim().is_empty()
82 }
83}