Skip to content

Commit a1731ab

Browse files
review: split up Table's CodingKeys to simplify its Codable implementation
Co-Authored-By: David Rönnqvist <[email protected]>
1 parent dac5a19 commit a1731ab

File tree

1 file changed

+37
-56
lines changed

1 file changed

+37
-56
lines changed

Sources/SwiftDocC/Model/Rendering/Content/RenderBlockContent.swift

Lines changed: 37 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -478,96 +478,77 @@ public enum RenderBlockContent: Equatable {
478478
// Writing a manual Codable implementation for tables because the encoding of `extendedData` does
479479
// not follow from the struct layout.
480480
extension RenderBlockContent.Table: Codable {
481-
// `extendedData` is encoded as a keyed container where the "keys" are the cell index, and
482-
// the "values" are the remaining fields in the struct. The key is formatted as a string with
483-
// the format "{row}_{column}", which is represented here as the `.index(row:column:)` enum
484-
// case. This CodingKey implementation performs that parsing and formatting so that the
485-
// Encodable/Decodable implementation can use the plain numbered indices.
486-
enum CodingKeys: CodingKey, Equatable {
481+
enum CodingKeys: String, CodingKey {
487482
case header, rows, extendedData, metadata
488-
case index(row: Int, column: Int)
489-
case colspan, rowspan
483+
}
490484

491-
var stringValue: String {
492-
switch self {
493-
case .header: return "header"
494-
case .rows: return "rows"
495-
case .extendedData: return "extendedData"
496-
case .metadata: return "metadata"
497-
case .colspan: return "colspan"
498-
case .rowspan: return "rowspan"
499-
case let .index(row, column): return "\(row)_\(column)"
500-
}
485+
// TableCellExtendedData encodes the row and column indices as a dynamic key with the format "{row}_{column}".
486+
struct DynamicIndexCodingKey: CodingKey, Equatable {
487+
let row, column: Int
488+
init(row: Int, column: Int) {
489+
self.row = row
490+
self.column = column
501491
}
502492

493+
var stringValue: String {
494+
return "\(row)_\(column)"
495+
}
503496
init?(stringValue: String) {
504-
switch stringValue {
505-
case "header": self = .header
506-
case "rows": self = .rows
507-
case "extendedData": self = .extendedData
508-
case "metadata": self = .metadata
509-
case "colspan": self = .colspan
510-
case "rowspan": self = .rowspan
511-
default:
512-
let coordinates = stringValue.split(separator: "_")
513-
guard coordinates.count == 2,
514-
let rowIndex = Int(coordinates.first!),
515-
let columnIndex = Int(coordinates.last!) else {
516-
return nil
517-
}
518-
self = .index(row: rowIndex, column: columnIndex)
497+
let coordinates = stringValue.split(separator: "_")
498+
guard coordinates.count == 2,
499+
let rowIndex = Int(coordinates.first!),
500+
let columnIndex = Int(coordinates.last!) else {
501+
return nil
519502
}
503+
row = rowIndex
504+
column = columnIndex
520505
}
521-
506+
// The key is only represented by a string value
522507
var intValue: Int? { nil }
508+
init?(intValue: Int) { nil }
509+
}
523510

524-
init?(intValue: Int) {
525-
return nil
526-
}
511+
enum ExtendedDataCodingKeys: String, CodingKey {
512+
case colspan, rowspan
527513
}
528514

529515
public init(from decoder: Decoder) throws {
530516
let container = try decoder.container(keyedBy: CodingKeys.self)
531517

518+
self.header = try container.decode(RenderBlockContent.HeaderType.self, forKey: .header)
519+
self.rows = try container.decode([RenderBlockContent.TableRow].self, forKey: .rows)
520+
self.metadata = try container.decodeIfPresent(RenderContentMetadata.self, forKey: .metadata)
521+
532522
var extendedData = Set<RenderBlockContent.TableCellExtendedData>()
533-
if container.allKeys.contains(.extendedData) {
534-
let dataContainer = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: .extendedData)
523+
if container.contains(.extendedData) {
524+
let dataContainer = try container.nestedContainer(keyedBy: DynamicIndexCodingKey.self, forKey: .extendedData)
535525

536526
for index in dataContainer.allKeys {
537-
guard case let .index(row, column) = index else { continue }
538-
539-
let cellContainer = try dataContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: index)
540-
extendedData.insert(.init(rowIndex: row,
541-
columnIndex: column,
527+
let cellContainer = try dataContainer.nestedContainer(keyedBy: ExtendedDataCodingKeys.self, forKey: index)
528+
extendedData.insert(.init(rowIndex: index.row,
529+
columnIndex: index.column,
542530
colspan: try cellContainer.decode(UInt.self, forKey: .colspan),
543531
rowspan: try cellContainer.decode(UInt.self, forKey: .rowspan)))
544532
}
545533
}
546-
547-
self = .init(header: try container.decode(RenderBlockContent.HeaderType.self, forKey: .header),
548-
rows: try container.decode([RenderBlockContent.TableRow].self, forKey: .rows),
549-
extendedData: extendedData,
550-
metadata: try container.decodeIfPresent(RenderContentMetadata.self, forKey: .metadata))
534+
self.extendedData = extendedData
551535
}
552536

553537
public func encode(to encoder: Encoder) throws {
554538
var container = encoder.container(keyedBy: CodingKeys.self)
555-
556539
try container.encode(header, forKey: .header)
557540
try container.encode(rows, forKey: .rows)
541+
try container.encodeIfPresent(metadata, forKey: .metadata)
558542

559543
if !extendedData.isEmpty {
560-
var dataContainer = container.nestedContainer(keyedBy: CodingKeys.self, forKey: .extendedData)
544+
var dataContainer = container.nestedContainer(keyedBy: DynamicIndexCodingKey.self, forKey: .extendedData)
561545
for data in extendedData {
562-
var cellContainer = dataContainer.nestedContainer(keyedBy: CodingKeys.self,
563-
forKey: .index(row: data.rowIndex,
564-
column: data.columnIndex))
546+
var cellContainer = dataContainer.nestedContainer(keyedBy: ExtendedDataCodingKeys.self,
547+
forKey: .init(row: data.rowIndex, column: data.columnIndex))
565548
try cellContainer.encode(data.colspan, forKey: .colspan)
566549
try cellContainer.encode(data.rowspan, forKey: .rowspan)
567550
}
568551
}
569-
570-
try container.encodeIfPresent(metadata, forKey: .metadata)
571552
}
572553
}
573554

0 commit comments

Comments
 (0)