tradingview-rs 0.2.0

Tradingview datafeed api `tradingview-rs` project.
Documentation
use std::time::Instant;

use crate::websocket::SeriesInfo;
use crate::{DataPoint, OHLCV, SymbolInfo};

#[derive(Debug)]
pub struct HistoricalState {
    pub data: Vec<DataPoint>,
    pub symbol_info: Option<SymbolInfo>,
    pub series_info: Option<SeriesInfo>,
    pub replay: ReplayState,
    pub error_count: u32,
    pub completed: bool,
    pub errored: bool,
    pub error_message: Option<String>,
    pub first_data_at: Option<Instant>,
    pub total_bars: usize,
}

impl HistoricalState {
    pub fn new() -> Self {
        Self {
            data: Vec::new(),
            symbol_info: None,
            series_info: None,
            replay: ReplayState::default(),
            error_count: 0,
            completed: false,
            errored: false,
            error_message: None,
            first_data_at: None,
            total_bars: 0,
        }
    }
    pub fn with_capacity(capacity: usize) -> Self {
        Self {
            data: Vec::with_capacity(capacity),
            ..Self::new()
        }
    }
    pub fn record_chart_data(&mut self, series_info: SeriesInfo, points: Vec<DataPoint>) {
        self.series_info = Some(series_info);
        let received = points.len();
        if self.first_data_at.is_none() {
            self.first_data_at = Some(Instant::now());
        }
        self.data.extend(points);
        self.total_bars += received;
    }
    pub fn record_symbol_info(&mut self, info: SymbolInfo) {
        self.symbol_info = Some(info);
    }
    pub fn record_error(&mut self) -> bool {
        self.error_count += 1;
        self.error_count > 5
    }
    pub fn complete(&mut self) {
        self.completed = true;
    }
    pub fn fail(&mut self, msg: String) {
        self.errored = true;
        self.error_message = Some(msg);
    }
    pub fn finalize(&mut self) -> Vec<DataPoint> {
        self.data.dedup_by_key(|p| p.timestamp());
        self.data.sort_by_key(|a| a.timestamp());
        std::mem::take(&mut self.data)
    }
}
impl Default for HistoricalState {
    fn default() -> Self {
        Self::new()
    }
}

#[derive(Debug, Default)]
pub struct ReplayState {
    pub enabled: bool,
    pub configured: bool,
    pub earliest_ts: Option<i64>,
    pub data_received: bool,
}
impl ReplayState {
    pub fn new(enabled: bool) -> Self {
        Self {
            enabled,
            ..Default::default()
        }
    }
    pub fn update_earliest(&mut self, ts: i64) {
        self.earliest_ts = Some(self.earliest_ts.map(|e| e.min(ts)).unwrap_or(ts));
    }
    pub fn needs_setup(&self) -> bool {
        self.enabled && !self.configured && self.data_received
    }
}