113 lines
2.9 KiB
Python
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
|