Add custom ExtJSON pretty printer to handle Mongo objects
This commit is contained in:
parent
54f8236332
commit
45e45a3991
|
@ -23,6 +23,7 @@
|
||||||
D627CE8824E399F100C39FE5 /* DetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627CE8624E399F100C39FE5 /* DetailViewController.swift */; };
|
D627CE8824E399F100C39FE5 /* DetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627CE8624E399F100C39FE5 /* DetailViewController.swift */; };
|
||||||
D627CE8924E399F100C39FE5 /* DetailViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D627CE8724E399F100C39FE5 /* DetailViewController.xib */; };
|
D627CE8924E399F100C39FE5 /* DetailViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D627CE8724E399F100C39FE5 /* DetailViewController.xib */; };
|
||||||
D627CE8B24E438EE00C39FE5 /* DatabaseCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627CE8A24E438EE00C39FE5 /* DatabaseCollection.swift */; };
|
D627CE8B24E438EE00C39FE5 /* DatabaseCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627CE8A24E438EE00C39FE5 /* DatabaseCollection.swift */; };
|
||||||
|
D627CE8D24E4478800C39FE5 /* JSONPrettyPrinter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627CE8C24E4478800C39FE5 /* JSONPrettyPrinter.swift */; };
|
||||||
D63CDEBE23C837DC0012D658 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63CDEBD23C837DC0012D658 /* AppDelegate.swift */; };
|
D63CDEBE23C837DC0012D658 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63CDEBD23C837DC0012D658 /* AppDelegate.swift */; };
|
||||||
D63CDEC023C837DD0012D658 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D63CDEBF23C837DD0012D658 /* Assets.xcassets */; };
|
D63CDEC023C837DD0012D658 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D63CDEBF23C837DD0012D658 /* Assets.xcassets */; };
|
||||||
D63CDEC323C837DD0012D658 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = D63CDEC123C837DD0012D658 /* MainMenu.xib */; };
|
D63CDEC323C837DD0012D658 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = D63CDEC123C837DD0012D658 /* MainMenu.xib */; };
|
||||||
|
@ -107,6 +108,7 @@
|
||||||
D627CE8624E399F100C39FE5 /* DetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailViewController.swift; sourceTree = "<group>"; };
|
D627CE8624E399F100C39FE5 /* DetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailViewController.swift; sourceTree = "<group>"; };
|
||||||
D627CE8724E399F100C39FE5 /* DetailViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DetailViewController.xib; sourceTree = "<group>"; };
|
D627CE8724E399F100C39FE5 /* DetailViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DetailViewController.xib; sourceTree = "<group>"; };
|
||||||
D627CE8A24E438EE00C39FE5 /* DatabaseCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseCollection.swift; sourceTree = "<group>"; };
|
D627CE8A24E438EE00C39FE5 /* DatabaseCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseCollection.swift; sourceTree = "<group>"; };
|
||||||
|
D627CE8C24E4478800C39FE5 /* JSONPrettyPrinter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONPrettyPrinter.swift; sourceTree = "<group>"; };
|
||||||
D63CDEBA23C837DC0012D658 /* MongoView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MongoView.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
D63CDEBA23C837DC0012D658 /* MongoView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MongoView.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
D63CDEBD23C837DC0012D658 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
D63CDEBD23C837DC0012D658 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
D63CDEBF23C837DD0012D658 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
D63CDEBF23C837DD0012D658 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
|
@ -234,6 +236,7 @@
|
||||||
D627CE8A24E438EE00C39FE5 /* DatabaseCollection.swift */,
|
D627CE8A24E438EE00C39FE5 /* DatabaseCollection.swift */,
|
||||||
D6D4665223CB730C00F13B1B /* MongoEvaluator.swift */,
|
D6D4665223CB730C00F13B1B /* MongoEvaluator.swift */,
|
||||||
D624090E243903E90020E09F /* ExtendedJSON.swift */,
|
D624090E243903E90020E09F /* ExtendedJSON.swift */,
|
||||||
|
D627CE8C24E4478800C39FE5 /* JSONPrettyPrinter.swift */,
|
||||||
D6A7D0A22435880700B46857 /* Synax Highlighting */,
|
D6A7D0A22435880700B46857 /* Synax Highlighting */,
|
||||||
D60C863B23CA2DD600C9DB8E /* Windows */,
|
D60C863B23CA2DD600C9DB8E /* Windows */,
|
||||||
D60C863C23CA2DDD00C9DB8E /* View Controllers */,
|
D60C863C23CA2DDD00C9DB8E /* View Controllers */,
|
||||||
|
@ -383,6 +386,7 @@
|
||||||
D63CDEBE23C837DC0012D658 /* AppDelegate.swift in Sources */,
|
D63CDEBE23C837DC0012D658 /* AppDelegate.swift in Sources */,
|
||||||
D6D4665323CB730C00F13B1B /* MongoEvaluator.swift in Sources */,
|
D6D4665323CB730C00F13B1B /* MongoEvaluator.swift in Sources */,
|
||||||
D624090F243903E90020E09F /* ExtendedJSON.swift in Sources */,
|
D624090F243903E90020E09F /* ExtendedJSON.swift in Sources */,
|
||||||
|
D627CE8D24E4478800C39FE5 /* JSONPrettyPrinter.swift in Sources */,
|
||||||
D63CDF3823C8381A0012D658 /* MongoController.swift in Sources */,
|
D63CDF3823C8381A0012D658 /* MongoController.swift in Sources */,
|
||||||
D60C863923CA2DD100C9DB8E /* ServerConnectWindowController.swift in Sources */,
|
D60C863923CA2DD100C9DB8E /* ServerConnectWindowController.swift in Sources */,
|
||||||
D63CDF3723C8381A0012D658 /* Node.swift in Sources */,
|
D63CDF3723C8381A0012D658 /* Node.swift in Sources */,
|
||||||
|
|
|
@ -19,6 +19,10 @@ struct ExtendedJSON {
|
||||||
return ["$oid": id]
|
return ["$oid": id]
|
||||||
}
|
}
|
||||||
context.setObject(objectId, forKeyedSubscript: "ObjectId" as NSString)
|
context.setObject(objectId, forKeyedSubscript: "ObjectId" as NSString)
|
||||||
|
let date: @convention(block) (String) -> [String: String] = { (date) in
|
||||||
|
return ["$date": date]
|
||||||
|
}
|
||||||
|
context.setObject(date, forKeyedSubscript: "Date" as NSString)
|
||||||
return context
|
return context
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -44,10 +48,4 @@ struct ExtendedJSON {
|
||||||
return doc
|
return doc
|
||||||
}
|
}
|
||||||
|
|
||||||
static func prettify(_ string: String) -> String? {
|
|
||||||
context.setObject(string, forKeyedSubscript: "value" as NSString)
|
|
||||||
let command = "JSON.stringify(JSON.parse(value), null, 4)"
|
|
||||||
return context.evaluateScript(command)?.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
//
|
||||||
|
// JSONPrettyPrinter.swift
|
||||||
|
// MongoView
|
||||||
|
//
|
||||||
|
// Created by Shadowfacts on 8/12/20.
|
||||||
|
// Copyright © 2020 Shadowfacts. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class JSONPrettyPrinter {
|
||||||
|
let options: Options
|
||||||
|
private var strings = [String]()
|
||||||
|
private var currentIndent = ""
|
||||||
|
|
||||||
|
init(options: Options) {
|
||||||
|
self.options = options
|
||||||
|
}
|
||||||
|
|
||||||
|
func prettify(_ string: String) throws -> String {
|
||||||
|
let object = try JSONSerialization.jsonObject(with: string.data(using: .utf8)!, options: [])
|
||||||
|
|
||||||
|
doPrettify(object)
|
||||||
|
|
||||||
|
return strings.joined(separator: "")
|
||||||
|
}
|
||||||
|
|
||||||
|
private func indent() {
|
||||||
|
currentIndent += "\t"
|
||||||
|
}
|
||||||
|
|
||||||
|
private func outdent() {
|
||||||
|
currentIndent = String(currentIndent.dropLast())
|
||||||
|
}
|
||||||
|
|
||||||
|
private func doPrettify(_ object: Any) {
|
||||||
|
if let dict = object as? [String: Any] {
|
||||||
|
if options.contains(.convertMongoObjects) && tryPrettifyMongoObject(dict) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
indent()
|
||||||
|
strings.append("{\n")
|
||||||
|
for (index, k) in dict.keys.sorted().enumerated() {
|
||||||
|
strings.append("\(currentIndent)\"\(escape(k))\"")
|
||||||
|
strings.append(": ")
|
||||||
|
doPrettify(dict[k]!)
|
||||||
|
if index != dict.count - 1 {
|
||||||
|
strings.append(",\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outdent()
|
||||||
|
strings.append("\n\(currentIndent)}")
|
||||||
|
} else if let arr = object as? [Any] {
|
||||||
|
indent()
|
||||||
|
strings.append("[\n")
|
||||||
|
for (index, v) in arr.enumerated() {
|
||||||
|
strings.append(currentIndent)
|
||||||
|
doPrettify(v)
|
||||||
|
if index != arr.count - 1 {
|
||||||
|
strings.append(",\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outdent()
|
||||||
|
strings.append("\n\(currentIndent)]")
|
||||||
|
} else if let str = object as? String {
|
||||||
|
strings.append("\"\(escape(str))\"")
|
||||||
|
} else if let bool = object as? Bool {
|
||||||
|
strings.append(bool.description)
|
||||||
|
} else if let num = object as? NSNumber {
|
||||||
|
strings.append(num.description)
|
||||||
|
} else if object is NSNull {
|
||||||
|
strings.append("null")
|
||||||
|
} else {
|
||||||
|
fatalError("unhandled object type: \(String(describing: object))")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func tryPrettifyMongoObject(_ dict: [String: Any]) -> Bool {
|
||||||
|
guard dict.count == 1 else { return false }
|
||||||
|
if let value = dict["$oid"] as? String {
|
||||||
|
strings.append("ObjectId(\"\(value)\")")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if let value = dict["$date"] as? String {
|
||||||
|
strings.append("Date(\"\(value)\")")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private func escape(_ str: String) -> String {
|
||||||
|
return str.replacingOccurrences(of: "\"", with: "\\\"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension JSONPrettyPrinter {
|
||||||
|
struct Options: OptionSet {
|
||||||
|
let rawValue: Int
|
||||||
|
|
||||||
|
static let convertMongoObjects = Options(rawValue: 1 << 0)
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,7 +37,9 @@ class EditDocumentViewController: NSViewController {
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
editorTextView.string = ExtendedJSON.prettify(document.extendedJSON) ?? document.extendedJSON
|
let printer = JSONPrettyPrinter(options: .convertMongoObjects)
|
||||||
|
editorTextView.string = (try? printer.prettify(document.extendedJSON)) ?? document.extendedJSON
|
||||||
|
|
||||||
editorTextView.isAutomaticQuoteSubstitutionEnabled = false
|
editorTextView.isAutomaticQuoteSubstitutionEnabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ class JavaScriptEditorView: NSTextView {
|
||||||
super.string
|
super.string
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
isRehighlighting = true
|
|
||||||
super.string = newValue
|
super.string = newValue
|
||||||
rehighlight()
|
rehighlight()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue