From 0e70044f7e303aae2133e5c1cc626f64f7742dd1 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Wed, 2 Jun 2021 15:44:30 +0100 Subject: [PATCH] Add search functions that take json as Data --- Sources/JMESPath/Expression.swift | 41 +++++++++++++++++++++++++++- Sources/JMESPath/Token.swift | 2 +- Sources/JMESPath/Variable.swift | 7 ++++- Tests/JMESPathTests/ErrorTests.swift | 2 +- 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/Sources/JMESPath/Expression.swift b/Sources/JMESPath/Expression.swift index b65db61..5add72f 100644 --- a/Sources/JMESPath/Expression.swift +++ b/Sources/JMESPath/Expression.swift @@ -14,6 +14,18 @@ public struct Expression { return self.init(ast) } + /// Search JSON + /// + /// - Parameters: + /// - any: JSON to search + /// - as: Swift type to return + /// - runtime: JMES runtime (includes functions) + /// - Throws: JMESPathError + /// - Returns: Search result + public func search(json: Data, as: Value.Type = Value.self, runtime: JMESRuntime = .init()) throws -> Value? { + return try self.search(json: json, runtime: runtime) as? Value + } + /// Search JSON /// /// - Parameters: @@ -26,7 +38,22 @@ public struct Expression { return try self.search(json: json, runtime: runtime) as? Value } - /// Search Swift type + /// Search JSON + /// + /// - Parameters: + /// - any: Swift type to search + /// - as: Swift type to return + /// - runtime: JMES runtime (includes functions) + /// - Throws: JMESPathError + /// - Returns: Search result + public func search(json: Data, as: Value.Type = Value.self, runtime: JMESRuntime = .init()) throws -> Value? { + if let rawValue = try self.search(json: json, runtime: runtime) as? Value.RawValue { + return Value(rawValue: rawValue) + } + return nil + } + + /// Search JSON /// /// - Parameters: /// - any: Swift type to search @@ -68,6 +95,18 @@ public struct Expression { return nil } + /// Search JSON + /// + /// - Parameters: + /// - any: JSON to search + /// - runtime: JMES runtime (includes functions) + /// - Throws: JMESPathError + /// - Returns: Search result + public func search(json: Data, runtime: JMESRuntime = .init()) throws -> Any? { + let value = try JMESVariable.fromJson(json) + return try runtime.interpret(value, ast: self.ast).collapse() + } + /// Search JSON /// /// - Parameters: diff --git a/Sources/JMESPath/Token.swift b/Sources/JMESPath/Token.swift index 9c153bc..75c4f79 100644 --- a/Sources/JMESPath/Token.swift +++ b/Sources/JMESPath/Token.swift @@ -64,7 +64,7 @@ extension Token: CustomStringConvertible { case .identifier(let string): return string case .quotedIdentifier(let string): return string case .number(let number): return "\(number)" - case .literal(_): return "`...`" + case .literal: return "`" case .dot: return "." case .star: return "*" case .flatten: return "[]" diff --git a/Sources/JMESPath/Variable.swift b/Sources/JMESPath/Variable.swift index 836801b..bd71dc2 100644 --- a/Sources/JMESPath/Variable.swift +++ b/Sources/JMESPath/Variable.swift @@ -60,7 +60,12 @@ public enum JMESVariable { /// create JMESVariable from json public static func fromJson(_ json: String) throws -> Self { - let object = try JSONSerialization.jsonObject(with: Data(json.utf8), options: [.allowFragments]) + return try self.fromJson(Data(json.utf8)) + } + + /// create JMESVariable from json + public static func fromJson(_ json: Data) throws -> Self { + let object = try JSONSerialization.jsonObject(with: json, options: [.allowFragments]) return JMESVariable(from: object) } diff --git a/Tests/JMESPathTests/ErrorTests.swift b/Tests/JMESPathTests/ErrorTests.swift index 4e7e642..e256f43 100644 --- a/Tests/JMESPathTests/ErrorTests.swift +++ b/Tests/JMESPathTests/ErrorTests.swift @@ -2,7 +2,7 @@ import XCTest final class ErrorTests: XCTestCase { - func testUnknownFunction() throws { + func testUnknownFunction() throws { let expression = try Expression.compile("unknown(@)") XCTAssertThrowsError(try expression.search("test")) { error in switch error {