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