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}