Skip to content

Commit ea0f3a9

Browse files
fix: Parser respects units with non-utf8 chars
Adds test
1 parent 92035fe commit ea0f3a9

2 files changed

Lines changed: 22 additions & 22 deletions

File tree

Sources/Units/Parser.swift

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Foundation
22

33
class Parser {
4-
var data: Data
4+
var data: [UnicodeScalar]
55
var position = 0
66

77
private var cur: Character? {
@@ -19,7 +19,7 @@ class Parser {
1919
}
2020

2121
init(_ string: String) {
22-
self.data = Data(string.utf8)
22+
self.data = Array(string.unicodeScalars)
2323
}
2424

2525
func parseMeasurement() throws -> Measurement {
@@ -154,28 +154,15 @@ class Parser {
154154
}
155155
return .number(number)
156156
}
157-
158-
if char.isLetter {
159-
var unitString = ""
160-
while let cur = cur, (cur.isLetter || cur.isNumber || OperatorSymbols.allCases.map{$0.rawValue}.contains(cur)) {
161-
unitString.append(cur)
162-
consume()
163-
}
164-
let unit = try Unit.init(fromSymbol: unitString)
165-
return .unit(unit)
166-
}
167-
168-
if char == "(" {
157+
else if char == "(" {
169158
consume()
170159
return .lParen
171160
}
172-
173-
if char == ")" {
161+
else if char == ")" {
174162
consume()
175163
return .rParen
176164
}
177-
178-
if char == "^" {
165+
else if char == "^" {
179166
let startPosition = position
180167
try consume("^")
181168
var intString = ""
@@ -188,8 +175,7 @@ class Parser {
188175
}
189176
return .exp(int)
190177
}
191-
192-
if char.isWhitespace {
178+
else if char.isWhitespace {
193179
if peek == "+" {
194180
try consume(" ")
195181
try consume("+")
@@ -219,8 +205,15 @@ class Parser {
219205
consume()
220206
return try next()
221207
}
222-
223-
throw ParserError.unexpectedCharacter(char, position: position)
208+
else {
209+
var unitString = ""
210+
while let cur = cur, cur != "(" && cur != ")" && !cur.isWhitespace {
211+
unitString.append(cur)
212+
consume()
213+
}
214+
let unit = try Unit.init(fromSymbol: unitString)
215+
return .unit(unit)
216+
}
224217
}
225218

226219
private func consume() {

Tests/UnitsTests/ParserTests.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ final class ParseMeasurementTests: XCTestCase {
1616
)
1717
}
1818

19+
func testUnitWithSymbol() throws {
20+
XCTAssertEqual(
21+
try Parser("5.1 °F").parseMeasurement(),
22+
5.1.measured(in: .fahrenheit)
23+
)
24+
}
25+
1926
func testComplexUnit() throws {
2027
XCTAssertEqual(
2128
try Parser("5.1 m^2*kg/s^3").parseMeasurement(),

0 commit comments

Comments
 (0)