polyester/codecs/
heatmap.rs1use buffa::Enumeration;
4
5use crate::errors::{Error, Result};
6use crate::proto::marketdata::v1::{HeatmapDepth, HeatmapInterval, HeatmapQuantityMode};
7
8pub fn resolve_heatmap_interval(value: &str) -> Result<HeatmapInterval> {
9 let key = heatmap_interval_channel_name(value);
10 HeatmapInterval::from_proto_name(&key)
11 .or_else(|| HeatmapInterval::from_proto_name(&key.to_ascii_uppercase()))
12 .ok_or_else(|| Error::validation(format!("unknown heatmap interval: {value}")))
13}
14
15pub fn heatmap_interval_channel_name(value: &str) -> String {
17 match value {
18 "1s" => "INTERVAL_1S".to_owned(),
19 "1m" => "INTERVAL_1M".to_owned(),
20 "5m" => "INTERVAL_5M".to_owned(),
21 "1h" => "INTERVAL_1H".to_owned(),
22 other => other.to_owned(),
23 }
24}
25
26pub fn heatmap_depth_for_levels(depth: u32) -> HeatmapDepth {
27 match depth {
28 0..=5 => HeatmapDepth::Depth5,
29 6..=10 => HeatmapDepth::Depth10,
30 11..=20 => HeatmapDepth::Depth20,
31 21..=50 => HeatmapDepth::Depth50,
32 51..=100 => HeatmapDepth::Depth100,
33 _ => HeatmapDepth::Depth200,
34 }
35}
36
37pub fn resolve_heatmap_quantity_mode(value: &str) -> Result<HeatmapQuantityMode> {
38 let lower = value.to_ascii_lowercase();
39 let key = match lower.as_str() {
40 "close" => "CLOSE",
41 "peak" => "PEAK",
42 _ => value,
43 };
44 HeatmapQuantityMode::from_proto_name(key)
45 .or_else(|| HeatmapQuantityMode::from_proto_name(&key.to_ascii_uppercase()))
46 .ok_or_else(|| Error::validation("quantity_mode must be 'close' or 'peak'"))
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn interval_aliases() {
55 assert_eq!(
56 resolve_heatmap_interval("1m").unwrap(),
57 HeatmapInterval::Interval1m
58 );
59 assert_eq!(
60 resolve_heatmap_interval("INTERVAL_1H").unwrap(),
61 HeatmapInterval::Interval1h
62 );
63 }
64
65 #[test]
66 fn depth_buckets() {
67 assert_eq!(heatmap_depth_for_levels(5), HeatmapDepth::Depth5);
68 assert_eq!(heatmap_depth_for_levels(50), HeatmapDepth::Depth50);
69 assert_eq!(heatmap_depth_for_levels(200), HeatmapDepth::Depth200);
70 }
71}