Skip to content

Commit

Permalink
Encode JSON with sorted keys by default
Browse files Browse the repository at this point in the history
  • Loading branch information
ethan-kusters committed May 7, 2022
1 parent bdd4a56 commit e59fd8b
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 35 deletions.
18 changes: 11 additions & 7 deletions Sources/SwiftDocC/Converter/RenderNode+Coding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,21 +104,25 @@ public enum RenderJSONEncoder {
/// process which should not be shared in other encoding units. Instead, call this API to create a new encoder for each render node you want to encode.
///
/// - Parameters:
/// - prettyPrint: If `true`, the encoder formats its output to make it easy to read; if `false`, the output is compact.
/// - prettyPrint: Whether or not the the encoder should pretty print the RenderJSON output.
///
/// If `true`, the encoder formats its output to make it easy to read. If `false`, the output is compact. If no value is provided, the ``shouldPrettyPrintOutputJSON`` default is used.
/// - emitVariantOverrides: Whether the encoder should emit the top-level ``RenderNode/variantOverrides`` property that holds language-
/// specific documentation data.
/// - Returns: The new JSON encoder.
public static func makeEncoder(
prettyPrint: Bool = shouldPrettyPrintOutputJSON,
prettyPrint: Bool? = nil,
emitVariantOverrides: Bool = true
) -> JSONEncoder {
let encoder = JSONEncoder()
let encoder = JSONEncoder.default

if prettyPrint {
if #available(macOS 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *) {
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
// Only modify the default encoder's pretty print formatting setting
// if a value was provided.
if let prettyPrint = prettyPrint {
if prettyPrint {
encoder.outputFormatting.insert(.prettyPrinted)
} else {
encoder.outputFormatting = [.prettyPrinted]
encoder.outputFormatting.subtract(.prettyPrinted)
}
}

Expand Down
9 changes: 1 addition & 8 deletions Sources/SwiftDocC/Indexing/Navigator/NavigatorIndex.swift
Original file line number Diff line number Diff line change
Expand Up @@ -929,16 +929,9 @@ extension NavigatorIndex {
if emitJSONRepresentation {
let renderIndex = RenderIndex.fromNavigatorIndex(navigatorIndex, with: self)

let jsonEncoder = JSONEncoder()
if shouldPrettyPrintOutputJSON {
jsonEncoder.outputFormatting = [.sortedKeys, .prettyPrinted]
} else {
jsonEncoder.outputFormatting = [.sortedKeys]
}

let jsonNavigatorIndexURL = outputURL.appendingPathComponent("index.json")
do {
let renderIndexData = try jsonEncoder.encode(renderIndex)
let renderIndexData = try JSONEncoder.default.encode(renderIndex)
try renderIndexData.write(to: jsonNavigatorIndexURL)
} catch {
self.problems.append(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,7 @@ indirect enum JSON: Codable {
extension JSON: CustomDebugStringConvertible {
var debugDescription: String {
let encoder = JSONEncoder()
if #available(macOS 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *) {
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
} else {
encoder.outputFormatting = [.prettyPrinted]
}
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]

do {
let data = try encoder.encode(self)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ class ExternalReferenceResolverServiceClient {
qos: .unspecified
)

private var encoder = JSONEncoder()

init(server: DocumentationServer, convertRequestIdentifier: String?) {
self.server = server
self.convertRequestIdentifier = convertRequestIdentifier
Expand All @@ -46,7 +44,7 @@ class ExternalReferenceResolverServiceClient {
guard let self = self else { return }

do {
let encodedRequest = try self.encoder.encode(
let encodedRequest = try JSONEncoder.default.encode(
ConvertRequestContextWrapper(
convertRequestIdentifier: self.convertRequestIdentifier,
payload: request
Expand All @@ -59,7 +57,7 @@ class ExternalReferenceResolverServiceClient {
payload: encodedRequest
)

let messageData = try self.encoder.encode(message)
let messageData = try JSONEncoder.default.encode(message)

self.server.process(messageData) { responseData in
defer { resultGroup.leave() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ private class LongRunningProcess: ExternalLinkResolving {
func sendAndWait<Request: Codable & CustomStringConvertible, Response: Codable>(request: Request?) throws -> Response {
if let request = request {
guard let requestString = String(
data: try JSONEncoder().encode(request), encoding: .utf8)?.appending("\n"),
data: try JSONEncoder.default.encode(request), encoding: .utf8)?.appending("\n"),
let requestData = requestString.data(using: .utf8)
else {
throw OutOfProcessReferenceResolver.Error.unableToEncodeRequestToClient(requestDescription: request.description)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public struct JSONPatchApplier {
return newValue
}

return try JSONEncoder().encode(appliedJSON)
return try JSONEncoder.default.encode(appliedJSON)
}

private func apply(_ operation: JSONPatchOperation, to json: JSON, originalPointer: JSONPointer) throws -> JSON? {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
This source file is part of the Swift.org open source project
Copyright (c) 2022 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception
See https://swift.org/LICENSE.txt for license information
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import Foundation

extension JSONEncoder {
/// The encoder that should be used when creating JSON files that
/// are written to disk.
static var `default`: JSONEncoder {
let encoder = JSONEncoder()
encoder.outputFormatting = [.sortedKeys]

if shouldPrettyPrintOutputJSON {
encoder.outputFormatting.insert(.prettyPrinted)
}

return encoder
}
}
12 changes: 3 additions & 9 deletions Tests/SwiftDocCTests/Converter/RenderNodeCodableTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,12 @@ class RenderNodeCodableTests: XCTestCase {
}
}

func testSortedKeys() throws {
guard #available(macOS 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *) else {
throw XCTSkip("Skipped on platforms that don't support JSONEncoder.OutputFormatting.sortedKeys")
}

// When prettyPrint is enabled, keys are sorted
func testPrettyPrinted() throws {
let encoderPretty = RenderJSONEncoder.makeEncoder(prettyPrint: true)
XCTAssertTrue(encoderPretty.outputFormatting.contains(.sortedKeys))
XCTAssertTrue(encoderPretty.outputFormatting.contains(.prettyPrinted))

// When prettyPrint is disabled, keys are not sorted
let encoderNotPretty = RenderJSONEncoder.makeEncoder(prettyPrint: false)
XCTAssertFalse(encoderNotPretty.outputFormatting.contains(.sortedKeys))
XCTAssertFalse(encoderNotPretty.outputFormatting.contains(.prettyPrinted))
}

func testEncodesVariantOverridesSetAsProperty() throws {
Expand Down

0 comments on commit e59fd8b

Please sign in to comment.