Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swap sortKeys bool for keySort function #315

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
## Main

##### Breaking

* Change the `sortKeys` options to a `keySort` function.
[Kevin Barrett](https://github.com/kevboh)

##### Enhancements

* None.

##### Bug Fixes

* None.

## 4.0.6

##### Breaking
Expand Down
46 changes: 25 additions & 21 deletions Sources/Yams/Emitter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import CYaml
#endif
import Foundation

/// A sort predicate applied to two `Node`s. Return `true` when the first node should be ordered
/// before the second.
public typealias NodeSort = (Node, Node) throws -> Bool

/// Produce a YAML string from objects.
///
/// - parameter objects: Sequence of Objects.
Expand All @@ -22,7 +26,7 @@ import Foundation
/// - parameter explicitStart: Explicit document start `---`.
/// - parameter explicitEnd: Explicit document end `...`.
/// - parameter version: YAML version directive.
/// - parameter sortKeys: Whether or not to sort Mapping keys in lexicographic order.
/// - parameter keySort: Sort function to apply to Mapping keys, or `nil` to not sort.
///
/// - returns: YAML string.
///
Expand All @@ -37,7 +41,7 @@ public func dump<Objects>(
explicitStart: Bool = false,
explicitEnd: Bool = false,
version: (major: Int, minor: Int)? = nil,
sortKeys: Bool = false) throws -> String
keySort: NodeSort? = nil) throws -> String
where Objects: Sequence {
func representable(from object: Any) throws -> NodeRepresentable {
if let representable = object as? NodeRepresentable {
Expand All @@ -56,7 +60,7 @@ public func dump<Objects>(
explicitStart: explicitStart,
explicitEnd: explicitEnd,
version: version,
sortKeys: sortKeys
keySort: keySort
)
}

Expand All @@ -71,7 +75,7 @@ public func dump<Objects>(
/// - parameter explicitStart: Explicit document start `---`.
/// - parameter explicitEnd: Explicit document end `...`.
/// - parameter version: YAML version directive.
/// - parameter sortKeys: Whether or not to sort Mapping keys in lexicographic order.
/// - parameter keySort: Sort function to apply to Mapping keys, or `nil` to not sort.
///
/// - returns: YAML string.
///
Expand All @@ -86,7 +90,7 @@ public func dump(
explicitStart: Bool = false,
explicitEnd: Bool = false,
version: (major: Int, minor: Int)? = nil,
sortKeys: Bool = false) throws -> String {
keySort: NodeSort? = nil) throws -> String {
return try serialize(
node: object.represented(),
canonical: canonical,
Expand All @@ -97,7 +101,7 @@ public func dump(
explicitStart: explicitStart,
explicitEnd: explicitEnd,
version: version,
sortKeys: sortKeys
keySort: keySort
)
}

Expand All @@ -112,7 +116,7 @@ public func dump(
/// - parameter explicitStart: Explicit document start `---`.
/// - parameter explicitEnd: Explicit document end `...`.
/// - parameter version: YAML version directive.
/// - parameter sortKeys: Whether or not to sort Mapping keys in lexicographic order.
/// - parameter keySort: Sort function to apply to Mapping keys, or `nil` to not sort.
///
/// - returns: YAML string.
///
Expand All @@ -127,7 +131,7 @@ public func serialize<Nodes>(
explicitStart: Bool = false,
explicitEnd: Bool = false,
version: (major: Int, minor: Int)? = nil,
sortKeys: Bool = false) throws -> String
keySort: NodeSort? = nil) throws -> String
where Nodes: Sequence, Nodes.Iterator.Element == Node {
let emitter = Emitter(
canonical: canonical,
Expand All @@ -138,7 +142,7 @@ public func serialize<Nodes>(
explicitStart: explicitStart,
explicitEnd: explicitEnd,
version: version,
sortKeys: sortKeys
keySort: keySort
)
try emitter.open()
try nodes.forEach(emitter.serialize)
Expand All @@ -157,7 +161,7 @@ public func serialize<Nodes>(
/// - parameter explicitStart: Explicit document start `---`.
/// - parameter explicitEnd: Explicit document end `...`.
/// - parameter version: YAML version directive.
/// - parameter sortKeys: Whether or not to sort Mapping keys in lexicographic order.
/// - parameter keySort: Sort function to apply to Mapping keys, or `nil` to not sort.
///
/// - returns: YAML string.
///
Expand All @@ -172,7 +176,7 @@ public func serialize(
explicitStart: Bool = false,
explicitEnd: Bool = false,
version: (major: Int, minor: Int)? = nil,
sortKeys: Bool = false) throws -> String {
keySort: NodeSort? = nil) throws -> String {
return try serialize(
nodes: [node],
canonical: canonical,
Expand All @@ -183,7 +187,7 @@ public func serialize(
explicitStart: explicitStart,
explicitEnd: explicitEnd,
version: version,
sortKeys: sortKeys
keySort: keySort
)
}

Expand Down Expand Up @@ -223,7 +227,7 @@ public final class Emitter {
public var version: (major: Int, minor: Int)?

/// Set if emitter should sort keys in lexicographic order.
public var sortKeys: Bool = false
public var keySort: NodeSort? = nil
}

/// Configuration options to use when emitting YAML.
Expand All @@ -244,7 +248,7 @@ public final class Emitter {
/// - parameter explicitStart: Explicit document start `---`.
/// - parameter explicitEnd: Explicit document end `...`.
/// - parameter version: The `%YAML` directive value or nil.
/// - parameter sortKeys: Set if emitter should sort keys in lexicographic order.
/// - parameter keySort: Sort function to apply to Mapping keys, or `nil` to not sort.
public init(canonical: Bool = false,
indent: Int = 0,
width: Int = 0,
Expand All @@ -253,7 +257,7 @@ public final class Emitter {
explicitStart: Bool = false,
explicitEnd: Bool = false,
version: (major: Int, minor: Int)? = nil,
sortKeys: Bool = false) {
keySort: NodeSort? = nil) {
options = Options(canonical: canonical,
indent: indent,
width: width,
Expand All @@ -262,7 +266,7 @@ public final class Emitter {
explicitStart: explicitStart,
explicitEnd: explicitEnd,
version: version,
sortKeys: sortKeys)
keySort: keySort)
// configure emitter
yaml_emitter_initialize(&emitter)
yaml_emitter_set_output(&self.emitter, { pointer, buffer, size in
Expand Down Expand Up @@ -378,17 +382,17 @@ extension Emitter.Options {
/// - parameter explicitStart: Explicit document start `---`.
/// - parameter explicitEnd: Explicit document end `...`.
/// - parameter version: The `%YAML` directive value or nil.
/// - parameter sortKeys: Set if emitter should sort keys in lexicographic order.
/// - parameter keySort: Sort function to apply to Mapping keys, or `nil` to not sort.
public init(canonical: Bool = false, indent: Int = 0, width: Int = 0, allowUnicode: Bool = false,
lineBreak: Emitter.LineBreak = .ln, version: (major: Int, minor: Int)? = nil,
sortKeys: Bool = false) {
keySort: NodeSort? = nil) {
self.canonical = canonical
self.indent = indent
self.width = width
self.allowUnicode = allowUnicode
self.lineBreak = lineBreak
self.version = version
self.sortKeys = sortKeys
self.keySort = keySort
}
}

Expand Down Expand Up @@ -462,8 +466,8 @@ extension Emitter {
mappingStyle)
}
try emit(&event)
if options.sortKeys {
try mapping.keys.sorted().forEach {
if let sort = options.keySort {
try mapping.keys.sorted(by: sort).forEach {
try self.serializeNode($0)
try self.serializeNode(mapping[$0]!) // swiftlint:disable:this force_unwrapping
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/Yams/Encoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -284,5 +284,5 @@ private func serialize(node: Node, options: Emitter.Options) throws -> String {
explicitStart: options.explicitStart,
explicitEnd: options.explicitEnd,
version: options.version,
sortKeys: options.sortKeys)
keySort: options.keySort)
}
2 changes: 1 addition & 1 deletion Tests/YamsTests/EmitterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ class EmitterTests: XCTestCase {
let yaml = try Yams.serialize(node: node)
let expected = "key3: value3\nkey2: value2\nkey1: value1\n"
XCTAssertEqual(yaml, expected)
let yamlSorted = try Yams.serialize(node: node, sortKeys: true)
let yamlSorted = try Yams.serialize(node: node, keySort: <)
let expectedSorted = "key1: value1\nkey2: value2\nkey3: value3\n"
XCTAssertEqual(yamlSorted, expectedSorted)
}
Expand Down
2 changes: 1 addition & 1 deletion Tests/YamsTests/EncoderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class EncoderTests: XCTestCase { // swiftlint:disable:this type_body_length
func testEncodingTopLevelStructuredSingleClass() {
// Mapping is a class which encodes as a dictionary through a single value container.
let mapping = Mapping.testValue
_testRoundTrip(of: mapping, with: YAMLEncoder.Options(sortKeys: true), expectedYAML: """
_testRoundTrip(of: mapping, with: YAMLEncoder.Options(keySort: <), expectedYAML: """
Apple: http://apple.com
localhost: http://127.0.0.1

Expand Down