use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
pub enum MarkerType {
#[default]
Circle,
TriangleUp,
TriangleDown,
Square,
Diamond,
Star,
ArrowUp,
ArrowDown,
}
impl MarkerType {
pub fn as_str(&self) -> &str {
match self {
MarkerType::Circle => "Circle",
MarkerType::TriangleUp => "Triangle Up",
MarkerType::TriangleDown => "Triangle Down",
MarkerType::Square => "Square",
MarkerType::Diamond => "Diamond",
MarkerType::Star => "Star",
MarkerType::ArrowUp => "Arrow Up",
MarkerType::ArrowDown => "Arrow Down",
}
}
pub fn all() -> Vec<MarkerType> {
vec![
MarkerType::Circle,
MarkerType::TriangleUp,
MarkerType::TriangleDown,
MarkerType::Square,
MarkerType::Diamond,
MarkerType::Star,
MarkerType::ArrowUp,
MarkerType::ArrowDown,
]
}
}
impl fmt::Display for MarkerType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
pub enum AnnotationPos {
#[default]
Above,
Below,
Left,
Right,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Annotation {
pub id: usize,
pub ts: DateTime<Utc>,
pub price: f64,
pub marker: MarkerType,
pub text: Option<String>,
pub position: AnnotationPos,
pub color: [u8; 4],
pub size: f32,
pub visible: bool,
}
impl Annotation {
pub fn new(id: usize, ts: DateTime<Utc>, price: f64) -> Self {
Self {
id,
ts,
price,
marker: MarkerType::Circle,
text: None,
position: AnnotationPos::Above,
color: [100, 149, 237, 255], size: 8.0,
visible: true,
}
}
pub fn with_text(id: usize, ts: DateTime<Utc>, price: f64, text: String) -> Self {
Self {
id,
ts,
price,
marker: MarkerType::Circle,
text: Some(text),
position: AnnotationPos::Above,
color: [255, 255, 255, 255], size: 8.0,
visible: true,
}
}
pub fn with_marker(mut self, marker: MarkerType) -> Self {
self.marker = marker;
self
}
pub fn with_color(mut self, color: [u8; 4]) -> Self {
self.color = color;
self
}
pub fn with_size(mut self, size: f32) -> Self {
self.size = size;
self
}
pub fn with_pos(mut self, position: AnnotationPos) -> Self {
self.position = position;
self
}
}
impl fmt::Display for Annotation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Annotation[{}, {}, Price: {:.2}{}]",
self.ts.format("%Y-%m-%d %H:%M:%S"),
self.marker,
self.price,
self.text
.as_ref()
.map(|t| format!(", Text: {t}"))
.unwrap_or_default()
)
}
}