pyth_lazer_protocol/
dynamic_value.rs1use std::collections::BTreeMap;
2
3use crate::time::{DurationUs, TimestampUs};
4use anyhow::bail;
5use derive_more::From;
6use serde::ser::{SerializeMap, SerializeSeq};
7use serde::Serialize;
8
9#[derive(Debug, Clone, PartialEq, From)]
10pub enum DynamicValue {
11 String(String),
12 F64(f64),
13 U64(u64),
14 I64(i64),
15 Bool(bool),
16 Timestamp(TimestampUs),
17 Duration(DurationUs),
18 Bytes(Vec<u8>),
19 List(Vec<DynamicValue>),
20 Map(BTreeMap<String, DynamicValue>),
21}
22
23impl Serialize for DynamicValue {
24 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
25 where
26 S: serde::Serializer,
27 {
28 match self {
29 DynamicValue::String(v) => serializer.serialize_str(v),
30 DynamicValue::F64(v) => serializer.serialize_f64(*v),
31 DynamicValue::U64(v) => serializer.serialize_u64(*v),
32 DynamicValue::I64(v) => serializer.serialize_i64(*v),
33 DynamicValue::Bool(v) => serializer.serialize_bool(*v),
34 DynamicValue::Timestamp(v) => serializer.serialize_u64(v.as_micros()),
35 DynamicValue::Duration(v) => {
36 serializer.serialize_str(&humantime::format_duration((*v).into()).to_string())
37 }
38 DynamicValue::Bytes(v) => serializer.serialize_str(&hex::encode(v)),
39 DynamicValue::List(v) => {
40 let mut seq_serializer = serializer.serialize_seq(Some(v.len()))?;
41 for element in v {
42 seq_serializer.serialize_element(element)?;
43 }
44 seq_serializer.end()
45 }
46 DynamicValue::Map(map) => {
47 let mut map_serializer = serializer.serialize_map(Some(map.len()))?;
48 for (k, v) in map {
49 map_serializer.serialize_entry(k, v)?;
50 }
51 map_serializer.end()
52 }
53 }
54 }
55}
56
57impl DynamicValue {
58 pub fn is_str(&self, field_name: &str) -> anyhow::Result<()> {
59 match self {
60 DynamicValue::String(_) => Ok(()),
61 _ => bail!("invalid value type for {field_name}: expected String, got {self:?}"),
62 }
63 }
64}