///|
pub(all) struct EvalContext {
targeting_key : String
attributes : Map[String, FlagValue]
} derive(Debug)
///|
pub fn context(targeting_key : String) -> EvalContext {
{ targeting_key, attributes: Map([]) }
}
///|
/// Creates a context without a stable user key. This is useful for
/// application-wide flags that do not use percentage rollout.
pub fn empty_context() -> EvalContext {
context("")
}
///|
pub fn EvalContext::with_attr(
self : EvalContext,
key : String,
value : FlagValue,
) -> EvalContext {
let next = self.attributes.copy()
next[key] = value
{ ..self, attributes: next }
}
///|
/// Adds or replaces a batch of attributes while keeping the original context
/// immutable for callers that need to reuse it across requests.
pub fn EvalContext::with_attrs(
self : EvalContext,
attributes : Array[(String, FlagValue)],
) -> EvalContext {
let next = self.attributes.copy()
for _, pair in attributes {
let (key, value) = pair
next[key] = value
}
{ ..self, attributes: next }
}
///|
pub fn EvalContext::with_targeting_key(
self : EvalContext,
targeting_key : String,
) -> EvalContext {
{ ..self, targeting_key, }
}
///|
pub fn EvalContext::get_attr(self : EvalContext, key : String) -> FlagValue? {
self.attributes.get(key)
}
///|
pub fn EvalContext::has_attr(self : EvalContext, key : String) -> Bool {
self.attributes.contains(key)
}
///|
pub fn EvalContext::attribute_count(self : EvalContext) -> Int {
self.attributes.length()
}
///|
pub fn EvalContext::merge(
self : EvalContext,
overlay : EvalContext,
) -> EvalContext {
let next = self.attributes.copy()
for key, value in overlay.attributes {
next[key] = value
}
let targeting_key = if overlay.targeting_key == "" {
self.targeting_key
} else {
overlay.targeting_key
}
{ targeting_key, attributes: next }
}