{-# LANGUAGE OverloadedLists #-}
module LaunchDarkly.Server.Details where
import Data.Aeson.Types (ToJSON, Value (..), toJSON)
import Data.Text (Text)
import GHC.Exts (fromList)
import GHC.Generics (Generic)
import GHC.Natural (Natural)
-- |
-- Combines the result of a flag evaluation with an explanation of how it was
-- calculated.
data EvaluationDetail value = EvaluationDetail
{ value :: !value
-- ^ The result of the flag evaluation. This will be either one of the
-- flag's variations or the default value passed by the application.
, variationIndex :: !(Maybe Integer)
-- ^ The index of the returned value within the flag's list of variations,
-- e.g. 0 for the first variation - or Nothing if the default value was
-- returned.
, reason :: !EvaluationReason
-- ^ Describes the main factor that influenced the flag evaluation value.
}
deriving (Generic, Eq, Show)
instance ToJSON a => ToJSON (EvaluationDetail a) where
toJSON = toJSON
-- | Defines the possible values of the Kind property of EvaluationReason.
data EvaluationReason
= -- | Indicates that the flag was off and therefore returned its configured
-- off value.
EvaluationReasonOff
| -- | indicates that the context key was specifically targeted for this flag.
EvaluationReasonTargetMatch
| EvaluationReasonRuleMatch
{ ruleIndex :: !Natural
-- ^ The index of the rule that was matched (0 being the first).
, ruleId :: !Text
-- ^ The unique identifier of the rule that was matched.
, inExperiment :: !Bool
-- ^ Whether the evaluation was part of an experiment. Is true if
-- the evaluation resulted in an experiment rollout *and* served
-- one of the variations in the experiment. Otherwise false.
}
| -- \^ Indicates that the context matched one of the flag's rules.
EvaluationReasonPrerequisiteFailed
{ prerequisiteKey :: !Text
-- ^ The flag key of the prerequisite that failed.
}
| -- \^ Indicates that the flag was considered off because it had at least
-- one prerequisite flag that either was off or did not return the desired
-- variation.
EvaluationReasonFallthrough
{ inExperiment :: !Bool
-- ^ Whether the evaluation was part of an experiment. Is
-- true if the evaluation resulted in an experiment rollout *and*
-- served one of the variations in the experiment. Otherwise false.
}
| -- \^ Indicates that the flag was on but the context did not match any targets
-- or rules.
EvaluationReasonError
{ errorKind :: !EvalErrorKind
-- ^ Describes the type of error.
}
-- \^ Indicates that the flag could not be evaluated, e.g. because it does
-- not exist or due to an unexpected error. In this case the result value
-- will be the default value that the caller passed to the client.
deriving (Generic, Eq, Show)
instance ToJSON EvaluationReason where
toJSON x = case x of
EvaluationReasonOff ->
Object $ fromList [("kind", "OFF")]
EvaluationReasonTargetMatch ->
Object $ fromList [("kind", "TARGET_MATCH")]
(EvaluationReasonRuleMatch ruleIndex ruleId True) ->
Object $ fromList [("kind", "RULE_MATCH"), ("ruleIndex", toJSON ruleIndex), ("ruleId", toJSON ruleId), ("inExperiment", toJSON True)]
(EvaluationReasonRuleMatch ruleIndex ruleId False) ->
Object $ fromList [("kind", "RULE_MATCH"), ("ruleIndex", toJSON ruleIndex), ("ruleId", toJSON ruleId)]
(EvaluationReasonPrerequisiteFailed prerequisiteKey) ->
Object $ fromList [("kind", "PREREQUISITE_FAILED"), ("prerequisiteKey", toJSON prerequisiteKey)]
EvaluationReasonFallthrough True ->
Object $ fromList [("kind", "FALLTHROUGH"), ("inExperiment", toJSON True)]
EvaluationReasonFallthrough False ->
Object $ fromList [("kind", "FALLTHROUGH")]
(EvaluationReasonError errorKind) ->
Object $ fromList [("kind", "ERROR"), ("errorKind", toJSON errorKind)]
isInExperiment :: EvaluationReason -> Bool
isInExperiment reason = case reason of
EvaluationReasonRuleMatch _ _ inExperiment -> inExperiment
EvaluationReasonFallthrough inExperiment -> inExperiment
_ -> False
-- | Defines the possible values of the errorKind property of EvaluationReason.
data EvalErrorKind
= -- | Indicates that there was an internal inconsistency in the flag data,
-- e.g. a rule specified a nonexistent variation.
EvalErrorKindMalformedFlag
| -- | Indicates that the caller provided a flag key that did not match any
-- known flag.
EvalErrorFlagNotFound
| -- | Indicates that the result value was not of the requested type, e.g.
-- you called boolVariationDetail but the value was an integer.
EvalErrorWrongType
| -- | Indicates that the caller tried to evaluate a flag before the client
-- had successfully initialized.
EvalErrorClientNotReady
| -- | Indicates that the caller tried to evaluate a flag with an invalid
-- context
EvalErrorInvalidContext
| -- | Indicates that some error was returned by the external feature store.
EvalErrorExternalStore !Text
deriving (Generic, Eq, Show)
instance ToJSON EvalErrorKind where
toJSON x = String $ case x of
EvalErrorKindMalformedFlag -> "MALFORMED_FLAG"
EvalErrorFlagNotFound -> "FLAG_NOT_FOUND"
EvalErrorWrongType -> "WRONG_TYPE"
EvalErrorClientNotReady -> "CLIENT_NOT_READY"
EvalErrorExternalStore _ -> "EXTERNAL_STORE_ERROR"
EvalErrorInvalidContext -> "ERROR_INVALID_CONTEXT"