1use std::collections::HashMap;
2
3use serde_json::Value;
4
5use crate::client::Options;
6use crate::errors::Result;
7use crate::event::Event;
8use crate::fields::FieldHolder;
9
10pub type DynamicFieldFunc = fn() -> Value;
12
13impl FieldHolder for Builder {
14 fn add(&mut self, data: HashMap<String, Value>) {
15 self.fields.extend(data);
16 }
17
18 fn add_field(&mut self, name: &str, value: Value) {
20 self.fields.insert(name.to_string(), value);
21 }
22
23 fn add_func<F>(&mut self, func: F)
26 where
27 F: Fn() -> Result<(String, Value)>,
28 {
29 while let Ok((name, value)) = func() {
30 self.add_field(&name, value);
31 }
32 }
33}
34
35#[derive(Debug, Clone)]
38pub struct Builder {
39 pub options: Options,
41 pub(crate) fields: HashMap<String, Value>,
42 dynamic_fields: Vec<(String, DynamicFieldFunc)>,
43}
44
45impl Builder {
46 pub fn new(options: Options) -> Self {
48 Self {
49 options,
50 fields: HashMap::new(),
51 dynamic_fields: Vec::new(),
52 }
53 }
54
55 pub fn add_dynamic_field(&mut self, name: &str, func: DynamicFieldFunc) {
58 self.dynamic_fields.push((name.to_string(), func));
59 }
60
61 pub fn new_event(&self) -> Event {
64 let mut e = Event::new(&self.options);
65 e.fields = self.fields.clone();
66 for (name, func) in &self.dynamic_fields {
67 e.add_field(name, func())
68 }
69 e
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 #[test]
78 fn test_builder_add() {
79 let mut builder = Builder::new(Options::default());
80 let mut d: HashMap<String, Value> = HashMap::new();
81 d.insert("key".to_string(), Value::String("value".to_string()));
82 builder.add(d);
83
84 assert!(builder.fields.contains_key("key"));
85 assert_eq!(builder.fields["key"], Value::String("value".to_string()));
86 }
87
88 #[test]
89 fn test_builder_add_conflict() {
90 let mut builder = Builder::new(Options::default());
91 let mut data1: HashMap<String, Value> = HashMap::new();
92 data1.insert("key".to_string(), Value::String("value".to_string()));
93 builder.add(data1);
94 let mut data2: HashMap<String, Value> = HashMap::new();
95 data2.insert("key".to_string(), serde_json::json!(["1", "2"]));
96 builder.add(data2);
97
98 assert_eq!(builder.fields["key"], serde_json::json!(["1", "2"]));
99 }
100}