1use std::fmt::Debug;
2use std::str::FromStr;
3
4#[cfg(feature = "async")]
5use async_trait::async_trait;
6
7use crate::error::Result;
8use crate::map::Map;
9use crate::path;
10use crate::value::{Value, ValueKind};
11
12pub trait Source: Debug {
14 fn clone_into_box(&self) -> Box<dyn Source + Send + Sync>;
15
16 fn collect(&self) -> Result<Map<String, Value>>;
19
20 fn collect_to(&self, cache: &mut Value) -> Result<()> {
22 self.collect()?
23 .into_iter()
24 .for_each(|(key, val)| set_value(cache, key, val));
25
26 Ok(())
27 }
28}
29
30fn set_value(cache: &mut Value, key: String, value: Value) {
31 match path::Expression::from_str(key.as_str()) {
32 Ok(expr) => expr.set(cache, value),
34
35 _ => path::Expression::root(key).set(cache, value),
37 }
38}
39
40#[cfg(feature = "async")]
55#[async_trait]
56pub trait AsyncSource: Debug + Sync {
57 async fn collect(&self) -> Result<Map<String, Value>>;
62
63 async fn collect_to(&self, cache: &mut Value) -> Result<()> {
65 self.collect()
66 .await?
67 .into_iter()
68 .for_each(|(key, val)| set_value(cache, key, val));
69
70 Ok(())
71 }
72}
73
74#[cfg(feature = "async")]
75impl Clone for Box<dyn AsyncSource + Send + Sync> {
76 fn clone(&self) -> Self {
77 self.to_owned()
78 }
79}
80
81impl Clone for Box<dyn Source + Send + Sync> {
82 fn clone(&self) -> Self {
83 self.clone_into_box()
84 }
85}
86
87impl Source for Vec<Box<dyn Source + Send + Sync>> {
88 fn clone_into_box(&self) -> Box<dyn Source + Send + Sync> {
89 Box::new((*self).clone())
90 }
91
92 fn collect(&self) -> Result<Map<String, Value>> {
93 let mut cache: Value = Map::<String, Value>::new().into();
94
95 for source in self {
96 source.collect_to(&mut cache)?;
97 }
98
99 if let ValueKind::Table(table) = cache.kind {
100 Ok(table)
101 } else {
102 unreachable!();
103 }
104 }
105}
106
107impl Source for [Box<dyn Source + Send + Sync>] {
108 fn clone_into_box(&self) -> Box<dyn Source + Send + Sync> {
109 Box::new(self.to_owned())
110 }
111
112 fn collect(&self) -> Result<Map<String, Value>> {
113 let mut cache: Value = Map::<String, Value>::new().into();
114
115 for source in self {
116 source.collect_to(&mut cache)?;
117 }
118
119 if let ValueKind::Table(table) = cache.kind {
120 Ok(table)
121 } else {
122 unreachable!();
123 }
124 }
125}
126
127impl<T> Source for Vec<T>
128where
129 T: Source + Sync + Send + Clone + 'static,
130{
131 fn clone_into_box(&self) -> Box<dyn Source + Send + Sync> {
132 Box::new((*self).clone())
133 }
134
135 fn collect(&self) -> Result<Map<String, Value>> {
136 let mut cache: Value = Map::<String, Value>::new().into();
137
138 for source in self {
139 source.collect_to(&mut cache)?;
140 }
141
142 if let ValueKind::Table(table) = cache.kind {
143 Ok(table)
144 } else {
145 unreachable!();
146 }
147 }
148}