Exemplo n.º 1
0
    private WorldLocation DeserializeObj(ref Utf8JsonReader reader, JsonSerializerOptions options)
    {
        Span <int> data   = stackalloc int[3];
        var        count  = 0;
        var        hasLoc = false;
        var        hasXYZ = false;
        var        hasMap = false;
        Map        map    = null;

        while (true)
        {
            reader.Read();
            if (reader.TokenType == JsonTokenType.EndObject)
            {
                break;
            }

            if (reader.TokenType != JsonTokenType.PropertyName)
            {
                throw new JsonException("Invalid Json structure for WorldLocation object");
            }

            var key = reader.GetString();

            var i = key switch
            {
                "x" => 0,
                "y" => 1,
                "z" => 2,
                "loc" => 3,
                "map" => 4,
                _ => 5
            };

            if (i == 5)
            {
                continue;
            }

            reader.Read();

            if (i < 3)
            {
                if (hasLoc)
                {
                    throw new JsonException("WorldLocation must have loc or x, y, z, but not both");
                }

                if (reader.TokenType != JsonTokenType.Number)
                {
                    throw new JsonException($"Value for {key} must be a number");
                }

                hasXYZ  = true;
                data[i] = reader.GetInt32();
                continue;
            }

            if (i == 3)
            {
                if (hasXYZ)
                {
                    throw new JsonException("WorldLocation must have loc or x, y, z, but not both");
                }

                hasLoc = true;

                _point3DConverter ??= new Point3DConverter();

                var loc = _point3DConverter.Read(ref reader, typeof(Point3D), options);
                data[0] = loc.X;
                data[1] = loc.Y;
                data[2] = loc.Z;
                count   = 3;
                continue;
            }

            _mapConverter ??= new MapConverter();
            map = _mapConverter.Read(ref reader, typeof(Map), options);

            hasMap = true;
        }

        if (!hasMap || count != 3)
        {
            throw new JsonException("WorldLocation must have an x, y, z, and map properties");
        }

        return(new WorldLocation(data[0], data[1], data[2], map));
    }