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