Definition jsonShape (s : shapeT) : json :=
  match s with
  | SArray1D a => JsonObject [
      ("@Shape", JsonString "Array1D");
      ("Length", JsonInteger (Z.of_N (shapeArray1DLength a)))
    ]
  | SArray2D a => JsonObject [
      ("@Shape", JsonString "Array2D");
      ("SizeX", JsonInteger (Z.of_N (shapeArray2DSizeX a)));
      ("SizeY", JsonInteger (Z.of_N (shapeArray2DSizeY a)))
    ]
  | SArray3D a => JsonObject [
      ("@Shape", JsonString "Array3D");
      ("SizeX", JsonInteger (Z.of_N (shapeArray3DSizeX a)));
      ("SizeY", JsonInteger (Z.of_N (shapeArray3DSizeY a)));
      ("SizeZ", JsonInteger (Z.of_N (shapeArray3DSizeZ a)))
    ]
  | SMesh a =>
    let index := jsonIndexOptional (shapeMeshIndex a) in
    let bounds := jsonBoundsOptional (shapeMeshBounds a) in
    let properties := [
      ("@Shape", JsonString "Mesh");
      ("Length", JsonInteger (Z.of_N (shapeMeshLength a)))
    ] in
      JsonObject (properties ++ index ++ bounds)
  end.
