-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
feature_flags.rs
104 lines (86 loc) · 3.27 KB
/
feature_flags.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
use crate::Rollout;
use indexmap::IndexSet;
use intern::string_key::StringKey;
use serde::{Deserialize, Serialize};
use std::fmt::{Display, Formatter, Result as FmtResult};
#[derive(Default, Debug, Serialize, Deserialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct FeatureFlags {
#[serde(default)]
pub enable_flight_transform: bool,
#[serde(default)]
pub enable_relay_resolver_transform: bool,
/// Enable hashing of the `supported` argument of 3D fields. Partial
/// enabling of the feature flag checks the name based on the field type.
#[serde(default)]
pub hash_supported_argument: FeatureFlag,
/// For now, this also disallows fragments with variable definitions
/// This also makes @module to opt in using @no_inline internally
/// NOTE that the presence of a fragment in this list only controls whether a fragment is *allowed* to
/// use @no_inline: whether the fragment is inlined or not depends on whether it actually uses that
/// directive.
#[serde(default)]
pub no_inline: FeatureFlag,
#[serde(default)]
pub enable_3d_branch_arg_generation: bool,
#[serde(default)]
pub actor_change_support: FeatureFlag,
/// Enable generation of text artifacts used to generate full query strings
/// later.
#[serde(default)]
pub text_artifacts: FeatureFlag,
#[serde(default)]
pub enable_client_edges: FeatureFlag,
#[serde(default)]
pub enable_provided_variables: FeatureFlag,
}
#[derive(Debug, Deserialize, Clone, Serialize)]
#[serde(tag = "kind", rename_all = "lowercase")]
pub enum FeatureFlag {
/// Fully disabled: developers may not use this feature
Disabled,
/// Fully enabled: developers may use this feature
Enabled,
/// Partially enabled: developers may only use this feature on the listed items (fragments, fields, types).
Limited { allowlist: IndexSet<StringKey> },
/// Partially enabled: used for gradual rollout of the feature
Rollout { rollout: Rollout },
}
impl Default for FeatureFlag {
fn default() -> Self {
FeatureFlag::Disabled
}
}
impl FeatureFlag {
pub fn is_enabled_for(&self, name: StringKey) -> bool {
match self {
FeatureFlag::Enabled => true,
FeatureFlag::Limited { allowlist } => allowlist.contains(&name),
FeatureFlag::Rollout { rollout } => rollout.check(name.lookup()),
FeatureFlag::Disabled => false,
}
}
pub fn is_fully_enabled(&self) -> bool {
matches!(self, FeatureFlag::Enabled)
}
}
impl Display for FeatureFlag {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
FeatureFlag::Disabled => f.write_str("disabled"),
FeatureFlag::Enabled => f.write_str("enabled"),
FeatureFlag::Limited { allowlist } => {
let items: Vec<_> = allowlist.iter().map(|x| x.lookup()).collect();
f.write_str("limited to: ")?;
f.write_str(&items.join(", "))
}
FeatureFlag::Rollout { rollout } => write!(f, "Rollout: {:#?}", rollout),
}
}
}