spin_factor_variables/
host.rs1use spin_factors::anyhow;
2use spin_telemetry::traces::{self, Blame};
3use spin_world::{v1, v2::variables, wasi::config as wasi_config};
4use tracing::instrument;
5
6use crate::InstanceState;
7
8impl variables::Host for InstanceState {
9 #[instrument(name = "spin_variables.get", skip(self), fields(otel.kind = "client"))]
10 async fn get(&mut self, key: String) -> Result<String, variables::Error> {
11 let key = spin_expressions::Key::new(&key).map_err(expressions_to_variables_err)?;
12 self.expression_resolver
13 .resolve(&self.component_id, key)
14 .await
15 .map_err(expressions_to_variables_err)
16 }
17
18 fn convert_error(&mut self, error: variables::Error) -> anyhow::Result<variables::Error> {
19 Ok(error)
20 }
21}
22
23impl v1::config::Host for InstanceState {
24 #[instrument(name = "spin_config.get", skip(self), fields(otel.kind = "client"))]
25 async fn get_config(&mut self, key: String) -> Result<String, v1::config::Error> {
26 <Self as variables::Host>::get(self, key)
27 .await
28 .map_err(|err| match err {
29 variables::Error::InvalidName(msg) => v1::config::Error::InvalidKey(msg),
30 variables::Error::Undefined(msg) => v1::config::Error::Provider(msg),
31 other => v1::config::Error::Other(format!("{other}")),
32 })
33 }
34
35 fn convert_error(&mut self, err: v1::config::Error) -> anyhow::Result<v1::config::Error> {
36 Ok(err)
37 }
38}
39
40impl wasi_config::store::Host for InstanceState {
41 #[instrument(name = "wasi_config.get", skip(self), fields(otel.kind = "client"))]
42 async fn get(&mut self, key: String) -> Result<Option<String>, wasi_config::store::Error> {
43 match <Self as variables::Host>::get(self, key).await {
44 Ok(value) => Ok(Some(value)),
45 Err(variables::Error::Undefined(_)) => Ok(None),
46 Err(variables::Error::InvalidName(_)) => Ok(None), Err(variables::Error::Provider(msg)) => Err(wasi_config::store::Error::Upstream(msg)),
48 Err(variables::Error::Other(msg)) => Err(wasi_config::store::Error::Io(msg)),
49 }
50 }
51
52 #[instrument(name = "wasi_config.get_all", skip(self), fields(otel.kind = "client"))]
53 async fn get_all(&mut self) -> Result<Vec<(String, String)>, wasi_config::store::Error> {
54 let all = self
55 .expression_resolver
56 .resolve_all(&self.component_id)
57 .await;
58 all.map_err(|e| {
59 match expressions_to_variables_err(e) {
60 variables::Error::Undefined(msg) => wasi_config::store::Error::Io(msg), variables::Error::InvalidName(msg) => wasi_config::store::Error::Io(msg), variables::Error::Provider(msg) => wasi_config::store::Error::Upstream(msg),
63 variables::Error::Other(msg) => wasi_config::store::Error::Io(msg),
64 }
65 })
66 }
67
68 fn convert_error(
69 &mut self,
70 err: wasi_config::store::Error,
71 ) -> anyhow::Result<wasi_config::store::Error> {
72 Ok(err)
73 }
74}
75
76fn expressions_to_variables_err(err: spin_expressions::Error) -> variables::Error {
78 use spin_expressions::Error;
79 let blame = match err {
80 Error::InvalidName(_) | Error::InvalidTemplate(_) | Error::Undefined(_) => Blame::Guest,
81 Error::Provider(_) => Blame::Host,
82 };
83 traces::mark_as_error(&err, Some(blame));
84 match err {
85 Error::InvalidName(msg) => variables::Error::InvalidName(msg),
86 Error::Undefined(msg) => variables::Error::Undefined(msg),
87 Error::InvalidTemplate(_) => variables::Error::Other(format!("{err}")),
88 Error::Provider(err) => variables::Error::Provider(err.to_string()),
89 }
90}