@@ -5,6 +5,8 @@ import Foundation
55/// unit of data exchange over the
66/// [HTTP API](https://project-haystack.org/doc/docHaystack/HttpApi).
77///
8+ /// To create a Grid, use a `GridBuilder`.
9+ ///
810/// [Docs](https://project-haystack.org/doc/docHaystack/Kinds#grid)
911public struct Grid : Val {
1012 public static var valType : ValType { . Grid }
@@ -22,30 +24,39 @@ public struct Grid: Val {
2224 /// Converts to Zinc formatted string.
2325 /// See [Zinc Literals](https://project-haystack.org/doc/docHaystack/Zinc#literals)
2426 public func toZinc( ) -> String {
25- var zinc = #"ver:"3.0""#
26- if meta. elements. count > 0 {
27- zinc += " \( meta. toZinc ( withBraces: false ) ) "
28- }
29- zinc += " \n "
27+ // Ensure `ver` is listed first in meta
28+ let ver = meta. elements [ " ver " ] ?? " 3.0 "
29+ var zinc = " ver: \( ver. toZinc ( ) ) "
3030
31- let zincCols = cols. map { col in
32- var colZinc = col. name
33- if let colMeta = col. meta, colMeta. elements. count > 0 {
34- colZinc += " \( colMeta. toZinc ( withBraces: false ) ) "
35- }
36- return colZinc
31+ var metaWithoutVer = meta. elements
32+ metaWithoutVer [ " ver " ] = nil
33+ if metaWithoutVer. count > 0 {
34+ zinc += " \( Dict ( metaWithoutVer) . toZinc ( withBraces: false ) ) "
3735 }
38- zinc += zincCols. joined ( separator: " , " )
3936 zinc += " \n "
4037
41- let zincRows = rows. map { row in
42- let rowZincElements = cols. map { col in
43- let element = row. elements [ col. name] ?? null
44- return element. toZinc ( )
38+ if cols. isEmpty {
39+ zinc += " empty \n "
40+ } else {
41+ let zincCols = cols. map { col in
42+ var colZinc = col. name
43+ if let colMeta = col. meta, colMeta. elements. count > 0 {
44+ colZinc += " \( colMeta. toZinc ( withBraces: false ) ) "
45+ }
46+ return colZinc
4547 }
46- return rowZincElements. joined ( separator: " , " )
48+ zinc += zincCols. joined ( separator: " , " )
49+ zinc += " \n "
50+
51+ let zincRows = rows. map { row in
52+ let rowZincElements = cols. map { col in
53+ let element = row. elements [ col. name] ?? null
54+ return element. toZinc ( )
55+ }
56+ return rowZincElements. joined ( separator: " , " )
57+ }
58+ zinc += zincRows. joined ( separator: " \n " )
4759 }
48- zinc += zincRows. joined ( separator: " \n " )
4960
5061 return zinc
5162 }
@@ -77,8 +88,14 @@ extension Grid {
7788 }
7889
7990 self . meta = try container. decode ( Dict . self, forKey: . meta)
80- self . cols = try container. decode ( [ Col ] . self, forKey: . cols)
81- self . rows = try container. decode ( [ Dict ] . self, forKey: . rows)
91+ let cols = try container. decode ( [ Col ] . self, forKey: . cols)
92+ if cols. map ( \. name) == [ " empty " ] {
93+ self . cols = [ ]
94+ self . rows = [ ]
95+ } else {
96+ self . cols = cols
97+ self . rows = try container. decode ( [ Dict ] . self, forKey: . rows)
98+ }
8299 } else {
83100 throw DecodingError . typeMismatch (
84101 Self . self,
@@ -96,8 +113,13 @@ extension Grid {
96113 var container = encoder. container ( keyedBy: Self . CodingKeys)
97114 try container. encode ( Self . kindValue, forKey: . _kind)
98115 try container. encode ( meta, forKey: . meta)
99- try container. encode ( cols, forKey: . cols)
100- try container. encode ( rows, forKey: . rows)
116+ if cols. isEmpty {
117+ try container. encode ( [ Col ( name: " empty " ) ] , forKey: . cols)
118+ try container. encode ( [ Dict] ( ) , forKey: . rows)
119+ } else {
120+ try container. encode ( cols, forKey: . cols)
121+ try container. encode ( rows, forKey: . rows)
122+ }
101123 }
102124}
103125
0 commit comments