private static EvaluationReason?ReadJsonInternal(ref JReader reader, bool nullable) { var obj = (nullable ? reader.ObjectOrNull() : reader.Object()) .WithRequiredProperties(_requiredProperties); if (!obj.IsDefined) { return(null); } try { EvaluationReasonKind kind = EvaluationReasonKind.Error; int? ruleIndex = null; string ruleId = null; string prerequisiteKey = null; EvaluationErrorKind?errorKind = null; bool inExperiment = false; BigSegmentsStatus?bigSegmentsStatus = null; while (obj.Next(ref reader)) { var name = obj.Name; if (name == "kind") { try { kind = EvaluationReasonKindConverter.FromIdentifier(reader.String()); } catch (ArgumentException) { throw new SyntaxException("unsupported value for \"kind\"", 0); } } else if (name == "ruleIndex") { ruleIndex = reader.Int(); } else if (name == "ruleId") { ruleId = reader.String(); } else if (name == "prerequisiteKey") { prerequisiteKey = reader.String(); } else if (name == "errorKind") { try { errorKind = EvaluationErrorKindConverter.FromIdentifier(reader.String()); } catch (ArgumentException) { throw new SyntaxException("unsupported value for \"errorKind\"", 0); } } else if (name == "inExperiment") { inExperiment = reader.Bool(); } else if (name == "bigSegmentsStatus") { try { bigSegmentsStatus = BigSegmentsStatusConverter.FromIdentifier(reader.String()); } catch (ArgumentException) { throw new SyntaxException("unsupported value for \"bigSegmentsStatus\"", 0); } } } EvaluationReason reason; switch (kind) // it's guaranteed to have a value, otherwise there'd be a required property error above { case EvaluationReasonKind.Off: reason = EvaluationReason.OffReason; break; case EvaluationReasonKind.Fallthrough: reason = EvaluationReason.FallthroughReason; break; case EvaluationReasonKind.TargetMatch: reason = EvaluationReason.TargetMatchReason; break; case EvaluationReasonKind.RuleMatch: reason = EvaluationReason.RuleMatchReason(ruleIndex ?? 0, ruleId); break; case EvaluationReasonKind.PrerequisiteFailed: reason = EvaluationReason.PrerequisiteFailedReason(prerequisiteKey); break; case EvaluationReasonKind.Error: reason = EvaluationReason.ErrorReason(errorKind ?? EvaluationErrorKind.Exception); break; default: return(null); } if (inExperiment) { reason = reason.WithInExperiment(true); } if (bigSegmentsStatus.HasValue) { reason = reason.WithBigSegmentsStatus(bigSegmentsStatus); } return(reason); } catch (Exception e) { throw reader.TranslateException(e); } }