Files
2026-01-28 19:33:35 +13:00

113 lines
2.9 KiB
Python

"""
Curve data validation
"""
from typing import Dict
def validate_schema(data: Dict) -> bool:
"""
Validate JSON data structure.
Args:
data: Parsed JSON data
Returns:
True if schema is valid, False otherwise
"""
# Check for required top-level keys
if not isinstance(data, dict):
return False
if "meta" not in data or "shapes" not in data:
return False
# Check meta structure
meta = data["meta"]
if not isinstance(meta, dict):
return False
required_meta = ["version", "width", "height"]
if not all(key in meta for key in required_meta):
return False
# Check shapes structure
shapes = data["shapes"]
if not isinstance(shapes, dict):
return False
# Validate each shape
for shape_id, shape in shapes.items():
if not isinstance(shape, dict):
return False
if "name" not in shape or "frames" not in shape:
return False
frames = shape["frames"]
if not isinstance(frames, dict):
return False
# Validate curves in each frame
for frame_num, curves in frames.items():
if not isinstance(curves, list):
return False
for curve in curves:
if not validate_curve(curve):
return False
return True
def validate_curve(curve: Dict) -> bool:
"""
Validate a single curve structure.
Args:
curve: Curve dictionary
Returns:
True if curve is valid, False otherwise
"""
if not isinstance(curve, dict):
return False
required_keys = ["id", "closed", "points"]
if not all(key in curve for key in required_keys):
return False
# Check points array
points = curve["points"]
if not isinstance(points, list):
return False
# Must have at least 2 points for a valid polygon
# For closed shapes, need at least 3 points
if len(points) < 2:
return False
if curve.get("closed", False) and len(points) < 3:
return False
# Each point must be [x, y] pair
for point in points:
if not isinstance(point, (list, tuple)) or len(point) != 2:
return False
if not all(isinstance(coord, (int, float)) for coord in point):
return False
# Validate optional pointTypes array
if "pointTypes" in curve:
point_types = curve["pointTypes"]
if not isinstance(point_types, list):
return False
# pointTypes length must match points length
if len(point_types) != len(points):
return False
# All values must be "smooth" or "hard"
valid_types = {"smooth", "hard"}
if not all(pt in valid_types for pt in point_types):
return False
return True