envoy_sdk/host/shared_data.rs
1// Copyright 2020 Tetrate
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! `Envoy` `Shared Data API`.
16
17use crate::host::{self, ByteString};
18
19pub use crate::abi::proxy_wasm::types::OptimisticLockVersion;
20
21/// An interface of the `Envoy` `Shared Data API`.
22///
23/// Basic usage of [`SharedData`]:
24///
25/// ```
26/// # use envoy_sdk as envoy;
27/// # use envoy::host::Result;
28/// # fn action() -> Result<()> {
29/// use envoy::host::SharedData;
30///
31/// let shared_data = SharedData::default();
32///
33/// let value = shared_data.get("shared_key")?;
34///
35/// shared_data.set("shared_key", b"shared value", None)?;
36/// # Ok(())
37/// # }
38/// ```
39///
40/// Injecting [`SharedData`] into a HTTP Filter as a dependency:
41///
42/// ```
43/// # use envoy_sdk as envoy;
44/// use envoy::host::SharedData;
45///
46/// struct MyHttpFilter<'a> {
47/// shared_data: &'a dyn SharedData,
48/// }
49///
50/// impl<'a> MyHttpFilter<'a> {
51/// /// Creates a new instance parameterized with a given [`SharedData`] implementation.
52/// pub fn new(shared_data: &'a dyn SharedData) -> Self {
53/// MyHttpFilter { shared_data }
54/// }
55///
56/// /// Creates a new instance parameterized with the default [`SharedData`] implementation.
57/// pub fn default() -> Self {
58/// Self::new(SharedData::default())
59/// }
60/// }
61/// ```
62///
63/// [`SharedData`]: trait.SharedData.html
64pub trait SharedData {
65 /// Returns shared data by key.
66 ///
67 /// # Arguments
68 ///
69 /// * `key` - key.
70 ///
71 /// # Return value
72 ///
73 /// * `value` - an opaque blob of bytes.
74 /// * `version` - optimistic lock version.
75 fn get(&self, key: &str) -> host::Result<(Option<ByteString>, Option<OptimisticLockVersion>)>;
76
77 /// Shares data under a given key.
78 ///
79 /// # Arguments
80 ///
81 /// * `key` - key.
82 /// * `value` - an opaque blob of bytes.
83 /// * `version` - optimistic lock version.
84 fn set(
85 &self,
86 key: &str,
87 value: &[u8],
88 version: Option<OptimisticLockVersion>,
89 ) -> host::Result<()>;
90}
91
92impl dyn SharedData {
93 /// Returns the default implementation that interacts with `Envoy`
94 /// through its [`ABI`].
95 ///
96 /// [`ABI`]: https://github.com/proxy-wasm/spec
97 pub fn default() -> &'static dyn SharedData {
98 &impls::Host
99 }
100}
101
102mod impls {
103 use super::SharedData;
104 use crate::abi::proxy_wasm::hostcalls;
105 use crate::abi::proxy_wasm::types::OptimisticLockVersion;
106 use crate::host::{self, ByteString};
107
108 pub(super) struct Host;
109
110 impl SharedData for Host {
111 fn get(
112 &self,
113 key: &str,
114 ) -> host::Result<(Option<ByteString>, Option<OptimisticLockVersion>)> {
115 hostcalls::get_shared_data(key)
116 }
117
118 fn set(
119 &self,
120 key: &str,
121 value: &[u8],
122 version: Option<OptimisticLockVersion>,
123 ) -> host::Result<()> {
124 hostcalls::set_shared_data(key, value, version)
125 }
126 }
127}