sinastock / src /models.rs
Spooker's picture
Upload 16 files
7c3e988 verified
use serde::Serialize;
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::RwLock;
#[derive(Clone)]
pub struct AppState {
pub latest: Arc<RwLock<HashMap<String, Quote>>>,
pub codes: Arc<Vec<String>>,
pub started_at: String,
}
impl AppState {
pub fn new(codes: Vec<String>, started_at: String) -> Self {
Self {
latest: Arc::new(RwLock::new(HashMap::new())),
codes: Arc::new(codes),
started_at,
}
}
}
#[derive(Clone, Debug, Serialize)]
pub struct Quote {
pub received_at: String,
pub code: String,
pub name: Option<String>,
pub previous_close: Option<String>,
pub open: Option<String>,
pub price: Option<String>,
pub high: Option<String>,
pub low: Option<String>,
pub bid1: Option<String>,
pub ask1: Option<String>,
pub volume: Option<String>,
pub amount: Option<String>,
pub trade_date: Option<String>,
pub trade_time: Option<String>,
pub status: Option<String>,
pub raw_fields: String,
pub fields: Vec<String>,
}
pub fn quote_from_record(record: &str, received_at: String) -> Option<Quote> {
let (code, raw_fields) = record.split_once('=')?;
let fields: Vec<String> = raw_fields
.split(',')
.map(|s| s.trim_matches('"').to_string())
.collect();
let get = |idx: usize| fields.get(idx).cloned().filter(|s| !s.is_empty());
// Sina WS fields used by this project:
// 名称, 昨收, 今开, 当前价, 最高, 最低, 买一价, 卖一价, 成交量, 成交额,
// 买5档×(量,价)×5, 卖5档×(量,价)×5, 日期, 时间, 状态
Some(Quote {
received_at,
code: code.to_string(),
name: get(0),
previous_close: get(1),
open: get(2),
price: get(3),
high: get(4),
low: get(5),
bid1: get(6),
ask1: get(7),
volume: get(8),
amount: get(9),
trade_date: get(30),
trade_time: get(31),
status: get(32),
raw_fields: raw_fields.to_string(),
fields,
})
}