open_feature/provider/
feature_provider.rs

1use async_trait::async_trait;
2
3use crate::{EvaluationContext, EvaluationResult, StructValue};
4
5use super::ResolutionDetails;
6
7// ============================================================
8//  FeatureProvider
9// ============================================================
10
11/// This trait defines interfaces that Provider Authors can use to abstract a particular flag
12/// management system, thus enabling the use of the evaluation API by Application Authors.
13///
14/// Providers are the "translator" between the flag evaluation calls made in application code, and
15/// the flag management system that stores flags and in some cases evaluates flags. At a minimum,
16/// providers should implement some basic evaluation methods which return flag values of the
17/// expected type. In addition, providers may transform the evaluation context appropriately in
18/// order to be used in dynamic evaluation of their associated flag management system, provide
19/// insight into why evaluation proceeded the way it did, and expose configuration options for
20/// their associated flag management system. Hypothetical provider implementations might wrap a
21/// vendor SDK, embed an REST client, or read flags from a local file.
22///
23/// See the [spec](https://openfeature.dev/specification/sections/providers).
24#[cfg_attr(feature = "test-util", mockall::automock)]
25#[async_trait]
26pub trait FeatureProvider: Send + Sync + 'static {
27    /// The provider MAY define an initialize function which accepts the global evaluation
28    /// context as an argument and performs initialization logic relevant to the provider.
29    ///
30    /// Note the following rules:
31    /// * The provider MUST set its status field/accessor to READY if its initialize function
32    /// terminates normally.
33    /// * The provider MUST set its status field to ERROR if its initialize function terminates
34    /// abnormally.
35    /// * The provider SHOULD indicate an error if flag resolution is attempted before the provider
36    /// is ready.
37    #[allow(unused_variables)]
38    async fn initialize(&mut self, context: &EvaluationContext) {}
39
40    /// The provider MAY define a status field/accessor which indicates the readiness of the
41    /// provider, with possible values NOT_READY, READY, or ERROR.
42    ///
43    /// Providers without this field can be assumed to be ready immediately.
44    fn status(&self) -> ProviderStatus {
45        ProviderStatus::Ready
46    }
47
48    /// The provider interface MUST define a metadata member or accessor, containing a name field
49    /// or accessor of type string, which identifies the provider implementation.
50    fn metadata(&self) -> &ProviderMetadata;
51
52    /// The provider MAY define a hooks field or accessor which returns a list of hooks that
53    /// the provider supports.
54    fn hooks(&self) -> &[crate::hooks::HookWrapper] {
55        &[]
56    }
57
58    /// Resolve given `flag_key` as a bool value.
59    async fn resolve_bool_value(
60        &self,
61        flag_key: &str,
62        evaluation_context: &EvaluationContext,
63    ) -> EvaluationResult<ResolutionDetails<bool>>;
64
65    /// Resolve given `flag_key` as an i64 value.
66    async fn resolve_int_value(
67        &self,
68        flag_key: &str,
69        evaluation_context: &EvaluationContext,
70    ) -> EvaluationResult<ResolutionDetails<i64>>;
71
72    /// Resolve given `flag_key` as a f64 value.
73    async fn resolve_float_value(
74        &self,
75        flag_key: &str,
76        evaluation_context: &EvaluationContext,
77    ) -> EvaluationResult<ResolutionDetails<f64>>;
78
79    /// Resolve given `flag_key` as a string value.
80    async fn resolve_string_value(
81        &self,
82        flag_key: &str,
83        evaluation_context: &EvaluationContext,
84    ) -> EvaluationResult<ResolutionDetails<String>>;
85
86    /// Resolve given `flag_key` as a struct value.
87    async fn resolve_struct_value(
88        &self,
89        flag_key: &str,
90        evaluation_context: &EvaluationContext,
91    ) -> EvaluationResult<ResolutionDetails<StructValue>>;
92}
93
94// ============================================================
95//  ProviderMetadata
96// ============================================================
97
98/// The metadata of a feature provider.
99#[derive(Clone, Default, Debug, PartialEq)]
100pub struct ProviderMetadata {
101    /// The name of provider.
102    pub name: String,
103}
104
105impl ProviderMetadata {
106    /// Create a new instance out of a string.
107    pub fn new<S: Into<String>>(name: S) -> Self {
108        Self { name: name.into() }
109    }
110}
111//
112// ============================================================
113//  ProviderStatus
114// ============================================================
115
116/// The status of a feature provider.
117#[derive(Default, PartialEq, Eq, Debug)]
118pub enum ProviderStatus {
119    /// The provider has not been initialized.
120    #[default]
121    NotReady,
122
123    /// The provider has been initialized, and is able to reliably resolve flag values.
124    Ready,
125
126    /// The provider is initialized but is not able to reliably resolve flag values.
127    Error,
128
129    /// The provider's cached state is no longer valid and may not be up-to-date with the source of
130    /// truth.
131    STALE,
132}