Skip to content

Commit 7649087

Browse files
Copilotolejnjak
andauthored
Support integers as cell values from Sheets API (#46)
* Initial plan * Support integers as cell values in ValueRange decoder Co-authored-by: olejnjak <3148214+olejnjak@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: olejnjak <3148214+olejnjak@users.noreply.github.com>
1 parent 749b4e1 commit 7649087

2 files changed

Lines changed: 60 additions & 0 deletions

File tree

‎Sources/ACKLocalizationCore/Model/ValueRange.swift‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,32 @@ public struct ValueRange: Decodable {
2222
public init(values: [[String]]) {
2323
self.values = values
2424
}
25+
26+
public init(from decoder: Decoder) throws {
27+
let container = try decoder.container(keyedBy: CodingKeys.self)
28+
let rawValues = try container.decode([[AnyCellValue]].self, forKey: .values)
29+
self.values = rawValues.map { $0.map(\.stringValue) }
30+
}
31+
32+
private enum CodingKeys: String, CodingKey {
33+
case values
34+
}
35+
}
36+
37+
/// A helper type that decodes a single sheet cell value, supporting strings and numbers.
38+
private struct AnyCellValue: Decodable {
39+
let stringValue: String
40+
41+
init(from decoder: Decoder) throws {
42+
let container = try decoder.singleValueContainer()
43+
if let string = try? container.decode(String.self) {
44+
stringValue = string
45+
} else if let int = try? container.decode(Int.self) {
46+
stringValue = String(int)
47+
} else if let double = try? container.decode(Double.self) {
48+
stringValue = String(double)
49+
} else {
50+
stringValue = ""
51+
}
52+
}
2553
}

‎Tests/ACKLocalizationCoreTests/ACKLocalizationTests.swift‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,36 @@ final class ACKLocalizationTests: XCTestCase {
4545
let fileName = "Localizable.strings"
4646
XCTAssertEqual("Localizable", fileName.removingSuffix(".strings"))
4747
}
48+
49+
func test_valueRange_decodesIntegerCellValues() throws {
50+
let json = #"{"values":[["key","en"],["some_key",42]]}"#
51+
let valueRange = try JSONDecoder().decode(ValueRange.self, from: Data(json.utf8))
52+
XCTAssertEqual(valueRange.values, [["key", "en"], ["some_key", "42"]])
53+
}
54+
55+
func test_valueRange_decodesDoubleCellValues() throws {
56+
let json = #"{"values":[["key","en"],["price_key",3.14]]}"#
57+
let valueRange = try JSONDecoder().decode(ValueRange.self, from: Data(json.utf8))
58+
XCTAssertEqual(valueRange.values, [["key", "en"], ["price_key", "3.14"]])
59+
}
60+
61+
func test_valueRange_decodesMixedCellValues() throws {
62+
let json = #"{"values":[["key","en"],["str_key","hello"],["int_key",7]]}"#
63+
let valueRange = try JSONDecoder().decode(ValueRange.self, from: Data(json.utf8))
64+
XCTAssertEqual(valueRange.values, [["key", "en"], ["str_key", "hello"], ["int_key", "7"]])
65+
}
66+
67+
func test_transform_integerCellValue() throws {
68+
let json = #"{"values":[["keys","en"],["count",42]]}"#
69+
let valueRange = try JSONDecoder().decode(ValueRange.self, from: Data(json.utf8))
70+
let mappedValues = try localization.transformValues(
71+
valueRange,
72+
with: ["en": "en"],
73+
keyColumnName: "keys"
74+
)
75+
XCTAssertEqual(
76+
mappedValues["en"],
77+
[LocRow(key: "count", value: "42")]
78+
)
79+
}
4880
}

0 commit comments

Comments
 (0)