private List <int> ReadInts(ref JReader r)
        {
            var ret = new List <int>();

            for (var arr = r.Array(); arr.Next(ref r);)
            {
                ret.Add(r.Int());
            }
            return(ret);
        }
        private List <TestStruct> ReadStructs(ref JReader r)
        {
            var ret = new List <TestStruct>();

            for (var arr = r.Array(); arr.Next(ref r);)
            {
                ret.Add(ReadStruct(ref r));
            }
            return(ret);
        }
        private List <bool> ReadBools(ref JReader r)
        {
            var ret = new List <bool>();

            for (var arr = r.Array(); arr.Next(ref r);)
            {
                ret.Add(r.Bool());
            }
            return(ret);
        }
        public object ReadJson(ref JReader reader)
        {
            string key = null;
            int    version = 0;
            bool   deleted = false;
            ImmutableList <string>      included = null, excluded = null;
            ImmutableList <SegmentRule> rules = null;
            string salt = null;

            for (var obj = reader.Object().WithRequiredProperties(_requiredProperties); obj.Next(ref reader);)
            {
                switch (obj.Name)
                {
                case var n when n == "key":
                    key = reader.String();
                    break;

                case var n when n == "version":
                    version = reader.Int();
                    break;

                case var n when n == "deleted":
                    deleted = reader.Bool();
                    break;

                case var n when n == "included":
                    included = SerializationHelpers.ReadStrings(ref reader);
                    break;

                case var n when n == "excluded":
                    excluded = SerializationHelpers.ReadStrings(ref reader);
                    break;

                case var n when n == "rules":
                    var rulesBuilder = ImmutableList.CreateBuilder <SegmentRule>();
                    for (var rulesArr = reader.Array(); rulesArr.Next(ref reader);)
                    {
                        rulesBuilder.Add(ReadSegmentRule(ref reader));
                    }
                    rules = rulesBuilder.ToImmutable();
                    break;

                case var n when n == "salt":
                    salt = reader.StringOrNull();
                    break;
                }
            }
            if (key is null && !deleted)
            {
                throw new RequiredPropertyException("key", 0);
            }
            return(new Segment(key, version, deleted, included, excluded, rules, salt));
        }