public void WriteReason(EvaluationReason?reason)
 {
     if (reason.HasValue)
     {
         EvaluationReasonConverter.WriteJsonValue(reason.Value, _obj.Name("reason"));
     }
 }
        public object ReadJson(ref JReader reader)
        {
            var valid = true;
            var flags = new Dictionary <string, FlagState>();

            for (var topLevelObj = reader.Object(); topLevelObj.Next(ref reader);)
            {
                var key = topLevelObj.Name.ToString();
                switch (key)
                {
                case "$valid":
                    valid = reader.Bool();
                    break;

                case "$flagsState":
                    for (var flagsObj = reader.Object(); flagsObj.Next(ref reader);)
                    {
                        var subKey = flagsObj.Name.ToString();
                        var flag   = flags.ContainsKey(subKey) ? flags[subKey] : new FlagState();
                        for (var metaObj = reader.Object(); metaObj.Next(ref reader);)
                        {
                            switch (metaObj.Name.ToString())
                            {
                            case "variation":
                                flag.Variation = reader.IntOrNull();
                                break;

                            case "version":
                                flag.Version = reader.IntOrNull();
                                break;

                            case "trackEvents":
                                flag.TrackEvents = reader.Bool();
                                break;

                            case "debugEventsUntilDate":
                                var n = reader.LongOrNull();
                                flag.DebugEventsUntilDate = n.HasValue ? UnixMillisecondTime.OfMillis(n.Value) :
                                                            (UnixMillisecondTime?)null;
                                break;

                            case "reason":
                                flag.Reason = EvaluationReasonConverter.ReadJsonNullableValue(ref reader);
                                break;
                            }
                        }
                        flags[subKey] = flag;
                    }
                    break;

                default:
                    var flagForValue = flags.ContainsKey(key) ? flags[key] : new FlagState();
                    flagForValue.Value = LdValueConverter.ReadJsonValue(ref reader);
                    flags[key]         = flagForValue;
                    break;
                }
            }
            return(new FeatureFlagsState(valid, flags));
        }
        public void WriteJson(object value, IValueWriter writer)
        {
            var state = value as FeatureFlagsState;

            if (state is null)
            {
                writer.Null();
                return;
            }

            var obj = writer.Object();

            foreach (var entry in state._flags)
            {
                LdValueConverter.WriteJsonValue(entry.Value.Value, obj.Name(entry.Key));
            }

            obj.Name("$valid").Bool(state._valid);

            var allMetadataObj = obj.Name("$flagsState").Object();

            foreach (var entry in state._flags)
            {
                var flagMetadataObj = allMetadataObj.Name(entry.Key).Object();
                var meta            = entry.Value;
                flagMetadataObj.Name("variation").IntOrNull(meta.Variation);
                flagMetadataObj.Name("version").IntOrNull(meta.Version);
                flagMetadataObj.MaybeName("trackEvents", meta.TrackEvents).Bool(meta.TrackEvents);
                flagMetadataObj.MaybeName("debugEventsUntilDate", meta.DebugEventsUntilDate.HasValue)
                .Long(meta.DebugEventsUntilDate?.Value ?? 0);
                if (meta.Reason.HasValue)
                {
                    EvaluationReasonConverter.WriteJsonValue(meta.Reason.Value, flagMetadataObj.Name("reason"));
                }
                flagMetadataObj.End();
            }
            allMetadataObj.End();

            obj.End();
        }