File size: 2,095 Bytes
7c3e988 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | 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,
})
}
|