Merge pull request #245 from ABridoux/bugfix/date-decoding

Date decoding
This commit is contained in:
Alexis Bridoux 2021-05-02 11:09:16 +02:00 committed by GitHub
commit eac87daded
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 107 additions and 27 deletions

View File

@ -6,6 +6,20 @@
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "Scout"
BuildableName = "Scout"
BlueprintName = "Scout"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
@ -48,20 +62,6 @@
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "Scout"
BuildableName = "Scout"
BlueprintName = "Scout"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction

View File

@ -121,10 +121,12 @@ extension ExplorerValue: Codable {
return .bool(bool)
} else if let data = try? container.decode(Data.self) {
return .data(data)
} else if let date = try? container.decode(Date.self) {
return .date(date)
} else if container.decodeNil() {
return .string("null")
} else {
throw ExplorerError(description: "Unable to decode single value in data. \(container.codingPath)")
throw ExplorerError(description: "Unable to decode single value in data. \(container.codingPath.pathDescription)")
}
}

View File

@ -42,14 +42,49 @@ public extension CodableFormats {
+ #"|(?<=\{)\s*"\#(foldedKey)"\s*:\s*"\#(foldedMark)"\s*(?=\})"# // dict
}
public static func encode<E: Encodable>(_ value: E, rootName: String?) throws -> Data {
private static let encoder: JSONEncoder = {
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
return try encoder.encode(value)
return encoder
}()
private static let decoder: JSONDecoder = JSONDecoder()
public static func encode<E: Encodable>(_ value: E, rootName: String?) throws -> Data {
try encoder.encode(value)
}
public static func decode<D>(_ type: D.Type, from data: Data) throws -> D where D: Decodable {
try JSONDecoder().decode(type, from: data)
try decoder.decode(type, from: data)
}
}
}
extension CodableFormats {
public enum JsonDateIso8601: CodableFormat {
public static let dataFormat: DataFormat = .json
public static var foldedRegexPattern: String { JsonDefault.foldedRegexPattern }
private static let decoder: JSONDecoder = {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
return decoder
}()
private static let encoder: JSONEncoder = {
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601
return encoder
}()
public static func decode<D>(_ type: D.Type, from data: Data) throws -> D where D : Decodable {
try decoder.decode(type, from: data)
}
public static func encode<E>(_ value: E, rootName: String?) throws -> Data where E : Encodable {
try encoder.encode(value)
}
}
}
@ -65,14 +100,20 @@ public extension CodableFormats {
+ #"|(?<=<dict>)\s*<key>\#(foldedKey)</key>\s*<string>\#(foldedMark)</string>\s*(?=</dict>)"# // dict
}
public static func encode<E>(_ value: E, rootName: String?) throws -> Data where E: Encodable {
private static let encoder: PropertyListEncoder = {
let encoder = PropertyListEncoder()
encoder.outputFormat = .xml
return try encoder.encode(value)
return encoder
}()
private static let decoder: PropertyListDecoder = PropertyListDecoder()
public static func encode<E>(_ value: E, rootName: String?) throws -> Data where E: Encodable {
try encoder.encode(value)
}
public static func decode<D>(_ type: D.Type, from data: Data) throws -> D where D: Decodable {
try PropertyListDecoder().decode(type, from: data)
try decoder.decode(type, from: data)
}
}
}
@ -88,12 +129,15 @@ public extension CodableFormats {
+ #"|\#(foldedKey)\s*:\s*\#(foldedMark)\s*(?=\n)"# // dict
}
private static let encoder = YAMLEncoder()
private static let decoder = YAMLDecoder()
public static func encode<E>(_ value: E, rootName: String?) throws -> Data where E: Encodable {
try YAMLEncoder().encode(value).data(using: .utf8).unwrapOrThrow(.stringToData)
try encoder.encode(value).data(using: .utf8).unwrapOrThrow(.stringToData)
}
public static func decode<D>(_ type: D.Type, from data: Data) throws -> D where D: Decodable {
try YAMLDecoder().decode(type, from: data)
try decoder.decode(type, from: data)
}
}
}

View File

@ -0,0 +1,34 @@
//
// Scout
// Copyright (c) 2020-present Alexis Bridoux
// MIT license, see LICENSE file for details
import Foundation
extension CodingKey {
/// Path element string description
var pathDescription: String {
let split = stringValue.components(separatedBy: " ")
if split.count == 2, split[0] == "Index", let index = Int(split[1]) {
return "[\(index)]"
} else {
return stringValue
}
}
}
extension Array where Element == CodingKey {
/// String description of the coding path
var pathDescription: String {
var path = reduce("") { "\($0)\($1.pathDescription)" }
if path.hasPrefix(".") {
path.removeFirst()
}
return path
}
}

View File

@ -7,7 +7,7 @@ import Foundation
import Scout
import ArgumentParser
/// Try to get a PathExplorer from the input
/// Try to get a `PathExplorer` from the input
protocol PathExplorerInputCommand: ParsableCommand {
/// A file path from which to read the data
@ -34,8 +34,8 @@ extension PathExplorerInputCommand {
func run() throws {
var filePath: String?
switch (inputFilePath?.replacingTilde, modifyFilePath?.replacingTilde) {
case (.some(let path), nil): filePath = path
case (nil, .some(let path)): filePath = path
case (let path?, nil): filePath = path
case (nil, let path?): filePath = path
case (nil, nil): break
case (.some, .some): throw RuntimeError.invalidArgumentsCombination(description: "Combining (-i|--input) with (-m|--modify) is not allowed")
}

View File

@ -6,6 +6,6 @@
import Scout
typealias Xml = PathExplorers.Xml
typealias Json = PathExplorers.Json
typealias Json = CodablePathExplorer<CodableFormats.JsonDateIso8601>
typealias Plist = PathExplorers.Plist
typealias Yaml = PathExplorers.Yaml