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}