Skip to content

Commit c9b1970

Browse files
committed
Replace NSNumber with JMESNumber
1 parent 3877a50 commit c9b1970

8 files changed

+347
-65
lines changed

.swift-format

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
{
2+
"version" : 1,
3+
"indentation" : {
4+
"spaces" : 4
5+
},
6+
"tabWidth" : 4,
7+
"fileScopedDeclarationPrivacy" : {
8+
"accessLevel" : "private"
9+
},
10+
"spacesAroundRangeFormationOperators" : false,
11+
"indentConditionalCompilationBlocks" : false,
12+
"indentSwitchCaseLabels" : false,
13+
"lineBreakAroundMultilineExpressionChainComponents" : false,
14+
"lineBreakBeforeControlFlowKeywords" : false,
15+
"lineBreakBeforeEachArgument" : true,
16+
"lineBreakBeforeEachGenericRequirement" : true,
17+
"lineLength" : 150,
18+
"maximumBlankLines" : 1,
19+
"respectsExistingLineBreaks" : true,
20+
"prioritizeKeepingFunctionOutputTogether" : true,
21+
"multiElementCollectionTrailingCommas" : true,
22+
"rules" : {
23+
"AllPublicDeclarationsHaveDocumentation" : false,
24+
"AlwaysUseLiteralForEmptyCollectionInit" : false,
25+
"AlwaysUseLowerCamelCase" : false,
26+
"AmbiguousTrailingClosureOverload" : true,
27+
"BeginDocumentationCommentWithOneLineSummary" : false,
28+
"DoNotUseSemicolons" : true,
29+
"DontRepeatTypeInStaticProperties" : true,
30+
"FileScopedDeclarationPrivacy" : true,
31+
"FullyIndirectEnum" : true,
32+
"GroupNumericLiterals" : true,
33+
"IdentifiersMustBeASCII" : true,
34+
"NeverForceUnwrap" : false,
35+
"NeverUseForceTry" : false,
36+
"NeverUseImplicitlyUnwrappedOptionals" : false,
37+
"NoAccessLevelOnExtensionDeclaration" : true,
38+
"NoAssignmentInExpressions" : true,
39+
"NoBlockComments" : true,
40+
"NoCasesWithOnlyFallthrough" : true,
41+
"NoEmptyTrailingClosureParentheses" : true,
42+
"NoLabelsInCasePatterns" : true,
43+
"NoLeadingUnderscores" : false,
44+
"NoParensAroundConditions" : true,
45+
"NoVoidReturnOnFunctionSignature" : true,
46+
"OmitExplicitReturns" : true,
47+
"OneCasePerLine" : true,
48+
"OneVariableDeclarationPerLine" : true,
49+
"OnlyOneTrailingClosureArgument" : true,
50+
"OrderedImports" : true,
51+
"ReplaceForEachWithForLoop" : true,
52+
"ReturnVoidInsteadOfEmptyTuple" : true,
53+
"UseEarlyExits" : false,
54+
"UseExplicitNilCheckInConditions" : false,
55+
"UseLetInEveryBoundCaseVariable" : false,
56+
"UseShorthandTypeNames" : true,
57+
"UseSingleLinePropertyGetter" : false,
58+
"UseSynthesizedInitializer" : false,
59+
"UseTripleSlashForDocumentationComments" : true,
60+
"UseWhereClausesInForLoops" : false,
61+
"ValidateDocumentationComments" : false
62+
}
63+
}

Sources/JMESPath/Expression.swift

+5-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public struct JMESExpression: JMESSendable {
2323
/// - Throws: JMESPathError
2424
/// - Returns: Search result
2525
public func search<Value>(json: Data, as: Value.Type = Value.self, runtime: JMESRuntime = .init()) throws -> Value? {
26-
return try self.search(json: json, runtime: runtime) as? Value
26+
try self.search(json: json, runtime: runtime) as? Value
2727
}
2828

2929
/// Search JSON
@@ -35,7 +35,7 @@ public struct JMESExpression: JMESSendable {
3535
/// - Throws: JMESPathError
3636
/// - Returns: Search result
3737
public func search<Value>(json: String, as: Value.Type = Value.self, runtime: JMESRuntime = .init()) throws -> Value? {
38-
return try self.search(json: json, runtime: runtime) as? Value
38+
try self.search(json: json, runtime: runtime) as? Value
3939
}
4040

4141
/// Search Swift type
@@ -47,7 +47,8 @@ public struct JMESExpression: JMESSendable {
4747
/// - Throws: JMESPathError
4848
/// - Returns: Search result
4949
public func search<Value>(object: Any, as: Value.Type = Value.self, runtime: JMESRuntime = .init()) throws -> Value? {
50-
return try self.search(object: object, runtime: runtime) as? Value
50+
let value = try self.search(object: object, runtime: runtime)
51+
return value as? Value
5152
}
5253

5354
/// Search JSON
@@ -82,7 +83,7 @@ public struct JMESExpression: JMESSendable {
8283
/// - Throws: JMESPathError
8384
/// - Returns: Search result
8485
public func search(object: Any, runtime: JMESRuntime = .init()) throws -> Any? {
85-
return try runtime.interpret(JMESVariable(from: object), ast: self.ast).collapse()
86+
try runtime.interpret(JMESVariable(from: object), ast: self.ast).collapse()
8687
}
8788

8889
private init(_ ast: Ast) {

Sources/JMESPath/Functions.swift

+42-34
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,7 @@ public struct FunctionSignature {
5050
/// - Parameter args: Array of arguments
5151
/// - Throws: JMESPathError.runtime
5252
func validateArgs(_ args: [JMESVariable]) throws {
53-
guard args.count == self.inputs.count ||
54-
(args.count > self.inputs.count && self.varArg != nil)
53+
guard args.count == self.inputs.count || (args.count > self.inputs.count && self.varArg != nil)
5554
else {
5655
throw JMESPathError.runtime("Invalid number of arguments, expected \(self.inputs.count), got \(args.count)")
5756
}
@@ -76,13 +75,13 @@ extension JMESVariable {
7675
func isType(_ type: FunctionSignature.ArgumentType) -> Bool {
7776
switch (self, type) {
7877
case (_, .any),
79-
(.string, .string),
80-
(.null, .null),
81-
(.number, .number),
82-
(.boolean, .boolean),
83-
(.array, .array),
84-
(.object, .object),
85-
(.expRef, .expRef):
78+
(.string, .string),
79+
(.null, .null),
80+
(.number, .number),
81+
(.boolean, .boolean),
82+
(.array, .array),
83+
(.object, .object),
84+
(.expRef, .expRef):
8685
return true
8786

8887
case (.array(let array), .typedArray(let elementType)):
@@ -128,7 +127,7 @@ public protocol JMESFunction {
128127

129128
/// Protocl for JMESPath function that takes a single number
130129
protocol NumberFunction: JMESFunction {
131-
static func evaluate(_ number: NSNumber) -> JMESVariable
130+
static func evaluate(_ number: JMESNumber) -> JMESVariable
132131
}
133132

134133
extension NumberFunction {
@@ -166,8 +165,8 @@ extension ArrayFunction {
166165
/// Returns the absolute value of the provided argument. The signature indicates that a number is returned, and that the
167166
/// input argument must resolve to a number, otherwise a invalid-type error is triggered.
168167
struct AbsFunction: NumberFunction {
169-
static func evaluate(_ number: NSNumber) -> JMESVariable {
170-
return .number(.init(value: abs(number.doubleValue)))
168+
static func evaluate(_ number: JMESNumber) -> JMESVariable {
169+
.number(number.abs())
171170
}
172171
}
173172

@@ -177,22 +176,22 @@ struct AvgFunction: ArrayFunction {
177176
static var signature: FunctionSignature { .init(inputs: .typedArray(.number)) }
178177
static func evaluate(_ array: JMESArray) -> JMESVariable {
179178
guard array.count > 0 else { return .null }
180-
let total = array.reduce(0.0) {
179+
let total = array.reduce(JMESNumber(0)) {
181180
if case .number(let number) = JMESVariable(from: $1) {
182-
return $0 + number.doubleValue
181+
return $0 + number
183182
} else {
184183
preconditionFailure()
185184
}
186185
}
187-
return .number(.init(value: total / Double(array.count)))
186+
return .number(total / JMESNumber(Double(array.count)))
188187
}
189188
}
190189

191190
/// `number ceil(number $value)`
192191
/// Returns the next highest integer value by rounding up if necessary.
193192
struct CeilFunction: NumberFunction {
194-
static func evaluate(_ number: NSNumber) -> JMESVariable {
195-
return .number(.init(value: ceil(number.doubleValue)))
193+
static func evaluate(_ number: JMESNumber) -> JMESVariable {
194+
.number(number.ceil())
196195
}
197196
}
198197

@@ -236,8 +235,8 @@ struct EndsWithFunction: JMESFunction {
236235
/// `number floor(number $value)`
237236
/// Returns the next lowest integer value by rounding down if necessary.
238237
struct FloorFunction: NumberFunction {
239-
static func evaluate(_ number: NSNumber) -> JMESVariable {
240-
return .number(.init(value: floor(number.doubleValue)))
238+
static func evaluate(_ number: JMESNumber) -> JMESVariable {
239+
.number(number.floor())
241240
}
242241
}
243242

@@ -289,11 +288,11 @@ struct LengthFunction: JMESFunction {
289288
static func evaluate(args: [JMESVariable], runtime: JMESRuntime) -> JMESVariable {
290289
switch args[0] {
291290
case .array(let array):
292-
return .number(.init(value: array.count))
291+
return .number(.init(array.count))
293292
case .object(let object):
294-
return .number(.init(value: object.count))
293+
return .number(.init(object.count))
295294
case .string(let string):
296-
return .number(.init(value: string.count))
295+
return .number(.init(string.count))
297296
default:
298297
preconditionFailure()
299298
}
@@ -342,7 +341,7 @@ struct MaxFunction: JMESFunction {
342341
case .number(var max):
343342
for element in array.dropFirst() {
344343
if case .number(let number) = JMESVariable(from: element) {
345-
if number.compare(max) == .orderedDescending {
344+
if number > max {
346345
max = number
347346
}
348347
}
@@ -389,7 +388,7 @@ struct MaxByFunction: JMESFunction {
389388
for element in array.dropFirst() {
390389
let value = try runtime.interpret(JMESVariable(from: element), ast: ast)
391390
if case .number(let number) = value {
392-
if number.compare(maxValue) == .orderedDescending {
391+
if number > maxValue {
393392
maxValue = number
394393
maxElement = element
395394
}
@@ -430,7 +429,7 @@ struct MinFunction: JMESFunction {
430429
case .number(var min):
431430
for element in array {
432431
if case .number(let number) = JMESVariable(from: element) {
433-
if number.compare(min) == .orderedAscending {
432+
if number < min {
434433
min = number
435434
}
436435
}
@@ -477,7 +476,7 @@ struct MinByFunction: JMESFunction {
477476
for element in array.dropFirst() {
478477
let value = try runtime.interpret(JMESVariable(from: element), ast: ast)
479478
if case .number(let number) = value {
480-
if number.compare(minValue) == .orderedAscending {
479+
if number < minValue {
481480
minValue = number
482481
minElement = element
483482
}
@@ -603,7 +602,9 @@ struct SortByFunction: JMESFunction {
603602
let restOfTheValues = try array.dropFirst().map { element -> ValueAndSortKey in
604603
let sortValue = try runtime.interpret(JMESVariable(from: element), ast: ast)
605604
guard sortValue.isSameType(as: firstSortValue) else {
606-
throw JMESPathError.runtime("Sort arguments all have to be the same type, expected \(firstSortValue.getType()), instead got \(sortValue.getType())")
605+
throw JMESPathError.runtime(
606+
"Sort arguments all have to be the same type, expected \(firstSortValue.getType()), instead got \(sortValue.getType())"
607+
)
607608
}
608609
return .init(value: element, sortValue: sortValue)
609610
}
@@ -636,14 +637,21 @@ struct StartsWithFunction: JMESFunction {
636637
struct SumFunction: ArrayFunction {
637638
static var signature: FunctionSignature { .init(inputs: .typedArray(.number)) }
638639
static func evaluate(_ array: JMESArray) -> JMESVariable {
639-
let total = array.reduce(0.0) {
640-
if case .number(let number) = JMESVariable(from: $1) {
641-
return $0 + number.doubleValue
642-
} else {
643-
preconditionFailure()
640+
guard let first = array.first.map({ JMESVariable(from: $0) }) else { return .number(.init(0)) }
641+
switch first {
642+
case .number(let number):
643+
let total = array.dropFirst().reduce(number) {
644+
if case .number(let number) = JMESVariable(from: $1) {
645+
return $0 + number
646+
} else {
647+
preconditionFailure()
648+
}
644649
}
650+
return .number(total)
651+
652+
default:
653+
preconditionFailure()
645654
}
646-
return .number(.init(value: total))
647655
}
648656
}
649657

@@ -709,7 +717,7 @@ struct ToStringFunction: JMESFunction {
709717
struct TypeFunction: JMESFunction {
710718
static var signature: FunctionSignature { .init(inputs: .any) }
711719
static func evaluate(args: [JMESVariable], runtime: JMESRuntime) throws -> JMESVariable {
712-
return .string(args[0].getType())
720+
.string(args[0].getType())
713721
}
714722
}
715723

Sources/JMESPath/Lexer.swift

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import Foundation
2-
31
/// Lexer object
42
///
53
/// Parses raw text to create an array of tokens
@@ -216,6 +214,6 @@ internal class Lexer {
216214
}
217215

218216
private func reachedEnd() -> Bool {
219-
return self.index == self.text.endIndex
217+
self.index == self.text.endIndex
220218
}
221219
}

0 commit comments

Comments
 (0)