commit
5b94054841
|
@ -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
|
||||
|
|
|
@ -3,7 +3,12 @@
|
|||
All notable changes to this project will be documented in this file. `Scout` adheres to [Semantic Versioning](http://semver.org).
|
||||
|
||||
---
|
||||
## [4.0.0](https://github.com/ABridoux/scout/tree/3.0.3) (28/04/2021)
|
||||
## [4.0.1](https://github.com/ABridoux/scout/tree/4.0.1) (02/05/2021)
|
||||
### Fixed
|
||||
- Date decoding and `PathExplorer.date` [#239]
|
||||
- `ExplorerXML` add and set features works with `ExplroerXML` values [#241]
|
||||
|
||||
## [4.0.0](https://github.com/ABridoux/scout/tree/4.0.0) (28/04/2021)
|
||||
### Added
|
||||
- Conversion from CSV input to one of the available formats [#181]
|
||||
- `Data` and `Date` values support [#197]
|
||||
|
|
|
@ -101,3 +101,16 @@ infix operator <|>: SequencePrecedence
|
|||
public func <|><A>(lhs: Parser<A>, rhs: Parser<A>) -> Parser<A> {
|
||||
lhs.or(rhs)
|
||||
}
|
||||
|
||||
infix operator <+>: SequencePrecedence
|
||||
public func <+><A>(lhs: Parser<A>, rhs: Parser<A>) -> Parser<[A]> {
|
||||
curry { [$0, $1] } <^> lhs <*> rhs
|
||||
}
|
||||
|
||||
public func <+><A>(lhs: Parser<[A]>, rhs: Parser<A>) -> Parser<[A]> {
|
||||
curry { $0 + [$1] } <^> lhs <*> rhs
|
||||
}
|
||||
|
||||
public func <+><A>(lhs: Parser<[A]>, rhs: Parser<[A]>) -> Parser<[A]> {
|
||||
curry { $0 + $1 } <^> lhs <*> rhs
|
||||
}
|
||||
|
|
|
@ -94,6 +94,23 @@ public extension Parser {
|
|||
}
|
||||
}
|
||||
|
||||
/// Match characters until one of the forbidden ones is encountered
|
||||
static func string(forbiddenCharacters isForbidden: @escaping (Character) -> Bool) -> Parser<String> {
|
||||
Parser<String> { input in
|
||||
guard !input.isEmpty else { return nil }
|
||||
var remainder = input
|
||||
var currentString = ""
|
||||
|
||||
while let char = remainder.first {
|
||||
if isForbidden(char) { break }
|
||||
currentString += String(char)
|
||||
remainder = remainder.dropFirst()
|
||||
}
|
||||
|
||||
return currentString.isEmpty ? nil : (currentString, remainder)
|
||||
}
|
||||
}
|
||||
|
||||
/// Match characters until the last ones equal the forbidden string, or if the character matches one of the forbidden ones
|
||||
///
|
||||
/// ### Examples
|
||||
|
|
|
@ -4,5 +4,5 @@
|
|||
// MIT license, see LICENSE file for details
|
||||
|
||||
public enum ScoutVersion {
|
||||
public static let current = "4.0.0"
|
||||
public static let current = "4.0.1"
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ extension ExplorerValue {
|
|||
|
||||
// MARK: General function
|
||||
|
||||
/// - parameter detailedName: When `true`, the key name after a filter will be composed of the parent key followed by the child key
|
||||
private func _get(path: SlicePath) throws -> Self {
|
||||
guard let (head, tail) = path.headAndTail() else { return self }
|
||||
|
||||
|
|
|
@ -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)")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,7 +192,12 @@ extension ExplorerValue {
|
|||
}
|
||||
|
||||
static func singleFrom(string: String) -> ExplorerValue {
|
||||
if let int = Int(string) { return .int(int) } else if let double = Double(string) { return .double(double) } else if let bool = Bool(string) { return .bool(bool) } else { return .string(string) }
|
||||
// swiftlint:disable statement_position
|
||||
if let int = Int(string) { return .int(int) }
|
||||
else if let double = Double(string) { return .double(double) }
|
||||
else if let bool = Bool(string) { return .bool(bool) }
|
||||
else { return .string(string) }
|
||||
// swiftlint:enable statement_position
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -277,6 +284,11 @@ extension ExplorerValue {
|
|||
return data
|
||||
}
|
||||
|
||||
public var date: Date? {
|
||||
guard case let .date(date) = self else { return nil }
|
||||
return date
|
||||
}
|
||||
|
||||
public var array: ArrayValue? {
|
||||
switch self {
|
||||
case .array(let array): return array
|
||||
|
|
|
@ -42,14 +42,50 @@ 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
|
||||
encoder.outputFormatting = .prettyPrinted
|
||||
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 +101,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 +130,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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,6 +126,12 @@ extension ExplorerValueDecoder {
|
|||
.unwrapOrThrow(.typeMismatch(Data.self, codingPath: codingPath + [key]))
|
||||
}
|
||||
|
||||
func decode(_ type: Date.Type, forKey key: Key) throws -> Date {
|
||||
try valueFor(key: key)
|
||||
.date
|
||||
.unwrapOrThrow(.typeMismatch(Date.self, codingPath: codingPath + [key]))
|
||||
}
|
||||
|
||||
func decode<T>(_ type: T.Type, forKey key: Key) throws -> T where T: Decodable {
|
||||
let value = try valueFor(key: key)
|
||||
|
||||
|
@ -133,6 +139,10 @@ extension ExplorerValueDecoder {
|
|||
return try decode(Data.self, forKey: key) as! T
|
||||
}
|
||||
|
||||
if T.self == Date.self {
|
||||
return try decode(Date.self, forKey: key) as! T
|
||||
}
|
||||
|
||||
let decoder = ExplorerValueDecoder(value, codingPath: codingPath + [key])
|
||||
return try T(from: decoder)
|
||||
}
|
||||
|
|
|
@ -74,11 +74,23 @@ extension ExplorerValueDecoder {
|
|||
try value.data.unwrapOrThrow(.typeMismatch(Data.self, codingPath: codingPath))
|
||||
}
|
||||
|
||||
func decode(_ type: Date.Type) throws -> Date {
|
||||
try value.date.unwrapOrThrow(.typeMismatch(Date.self, codingPath: codingPath))
|
||||
}
|
||||
|
||||
func decode<T>(_ type: T.Type) throws -> T where T: Decodable {
|
||||
if T.self == Data.self {
|
||||
return try decode(Data.self) as! T
|
||||
}
|
||||
|
||||
if T.self == Date.self {
|
||||
return try decode(Date.self) as! T
|
||||
}
|
||||
|
||||
if T.self == Date.self {
|
||||
return try decode(Date.self) as! T
|
||||
}
|
||||
|
||||
let decoder = ExplorerValueDecoder(value, codingPath: codingPath)
|
||||
return try T(from: decoder)
|
||||
}
|
||||
|
|
|
@ -107,11 +107,21 @@ extension ExplorerValueDecoder {
|
|||
return value
|
||||
}
|
||||
|
||||
mutating func decode(_ type: Date.Type) throws -> Date {
|
||||
let value = try array[currentIndex].date.unwrapOrThrow(.typeMismatch(Date.self, codingPath: codingPath))
|
||||
currentIndex += 1
|
||||
return value
|
||||
}
|
||||
|
||||
mutating func decode<T>(_ type: T.Type) throws -> T where T: Decodable {
|
||||
if T.self == Data.self {
|
||||
return try decode(Data.self) as! T
|
||||
}
|
||||
|
||||
if T.self == Date.self {
|
||||
return try decode(Date.self) as! T
|
||||
}
|
||||
|
||||
let decoder = ExplorerValueDecoder(array[currentIndex], codingPath: codingPath)
|
||||
let decoded = try T(from: decoder)
|
||||
currentIndex += 1
|
||||
|
|
|
@ -74,12 +74,21 @@ extension ExplorerValueEncoder {
|
|||
try encoder.value.add(.data(value), at: path.appending(key.stringValue))
|
||||
}
|
||||
|
||||
mutating func encode(_ value: Date, forKey key: Key) throws {
|
||||
try encoder.value.add(.date(value), at: path.appending(key.stringValue))
|
||||
}
|
||||
|
||||
mutating func encode<T>(_ value: T, forKey key: Key) throws where T: Encodable {
|
||||
if let data = value as? Data {
|
||||
try encode(data, forKey: key)
|
||||
return
|
||||
}
|
||||
|
||||
if let data = value as? Date {
|
||||
try encode(data, forKey: key)
|
||||
return
|
||||
}
|
||||
|
||||
let newEncoder = ExplorerValueEncoder()
|
||||
try value.encode(to: newEncoder)
|
||||
try encoder.value.add(newEncoder.value, at: path.appending(key.stringValue))
|
||||
|
|
|
@ -74,12 +74,21 @@ extension ExplorerValueEncoder {
|
|||
try encoder.value.set(path, to: .data(value))
|
||||
}
|
||||
|
||||
mutating func encode(_ value: Date) throws {
|
||||
try encoder.value.set(path, to: .date(value))
|
||||
}
|
||||
|
||||
mutating func encode<T>(_ value: T) throws where T: Encodable {
|
||||
if let data = value as? Data {
|
||||
try encode(data)
|
||||
return
|
||||
}
|
||||
|
||||
if let date = value as? Date {
|
||||
try encode(date)
|
||||
return
|
||||
}
|
||||
|
||||
let newEncoder = ExplorerValueEncoder(codingPath: codingPath)
|
||||
try value.encode(to: encoder)
|
||||
try encoder.value.set(path, to: newEncoder.value)
|
||||
|
|
|
@ -91,12 +91,22 @@ extension ExplorerValueEncoder {
|
|||
count += 1
|
||||
}
|
||||
|
||||
mutating func encode(_ value: Date) throws {
|
||||
try encoder.value.add(.date(value), at: path.appending(.count))
|
||||
count += 1
|
||||
}
|
||||
|
||||
mutating func encode<T>(_ value: T) throws where T: Encodable {
|
||||
if let data = value as? Data {
|
||||
try encode(data)
|
||||
return
|
||||
}
|
||||
|
||||
if let date = value as? Date {
|
||||
try encode(date)
|
||||
return
|
||||
}
|
||||
|
||||
let newEncoder = ExplorerValueEncoder(codingPath: codingPath)
|
||||
try value.encode(to: newEncoder)
|
||||
try encoder.value.add(newEncoder.value, at: path.appending(.count))
|
||||
|
|
|
@ -14,12 +14,38 @@ extension ExplorerXML {
|
|||
try _add(value: .explorerValue(value), at: Slice(path))
|
||||
}
|
||||
|
||||
/// Add the given `AEXMLElement` value rather than an `ExplorerValue`
|
||||
public mutating func add(_ element: Element, at path: Path) throws {
|
||||
if referenceIsShared() { self = copy() }
|
||||
try _add(value: .explorerXML(ExplorerXML(element: element)), at: Slice(path))
|
||||
}
|
||||
|
||||
/// Add the given `ExplorerXML` value rather than an `ExplorerValue`
|
||||
public mutating func add(_ explorer: ExplorerXML, at path: Path) throws {
|
||||
if referenceIsShared() { self = copy() }
|
||||
try _add(value: .explorerXML(explorer), at: Slice(path))
|
||||
}
|
||||
|
||||
public func adding(_ value: ExplorerValue, at path: Path) throws -> ExplorerXML {
|
||||
var copy = self.copy()
|
||||
try copy.add(value, at: path)
|
||||
return copy
|
||||
}
|
||||
|
||||
/// Add the given `AEXMLElement` value rather than an `ExplorerValue`
|
||||
public func adding(_ element: Element, at path: Path) throws -> ExplorerXML {
|
||||
var copy = self.copy()
|
||||
try copy.add(element, at: path)
|
||||
return copy
|
||||
}
|
||||
|
||||
/// Add the given `ExplorerXML` value rather than an `ExplorerValue`
|
||||
public func adding(_ explorerXML: ExplorerXML, at path: Path) throws -> ExplorerXML {
|
||||
var copy = self.copy()
|
||||
try copy.add(explorerXML, at: path)
|
||||
return copy
|
||||
}
|
||||
|
||||
// MARK: General function
|
||||
|
||||
/// Return the value if it should be added to the parent
|
||||
|
|
|
@ -16,21 +16,33 @@ extension ExplorerXML {
|
|||
try _set(path: Slice(path), to: .explorerValue(newValue))
|
||||
}
|
||||
|
||||
/// Set the path to the given `AEXMLElement` value rather than an `ExplorerValue`
|
||||
public mutating func set(_ path: Path, to element: Element) throws {
|
||||
try _set(path: Slice(path), to: .explorerXML(ExplorerXML(element: element)))
|
||||
}
|
||||
|
||||
/// Set the path to the given `ExplorerXML` value rather than an `ExplorerValue`
|
||||
public mutating func set(_ path: Path, to explorer: ExplorerXML) throws {
|
||||
try _set(path: Slice(path), to: .explorerXML(explorer))
|
||||
}
|
||||
|
||||
public func setting(_ path: Path, to newValue: ExplorerValue) throws -> ExplorerXML {
|
||||
var modified = copy()
|
||||
try modified.set(path, to: newValue)
|
||||
return modified
|
||||
}
|
||||
|
||||
/// Set the path to the given AEXMLElement rather than an `ExplorerValue`
|
||||
public mutating func set(_ path: Path, to newElement: Element) throws {
|
||||
try _set(path: Slice(path), to: .xmlElement(newElement))
|
||||
/// Set the path to the given `AEXMLElement` value rather than an `ExplorerValue`
|
||||
public func setting(_ path: Path, to element: Element) throws -> ExplorerXML {
|
||||
var modified = copy()
|
||||
try modified.set(path, to: element)
|
||||
return modified
|
||||
}
|
||||
|
||||
/// Set the path to the given AEXMLElement rather than an `ExplorerValue`
|
||||
public func setting(_ path: Path, to newElement: Element) throws -> ExplorerXML {
|
||||
/// Set the path to the given `ExplorerXML` value rather than an `ExplorerValue`
|
||||
public func setting(_ path: Path, to explorer: ExplorerXML) throws -> ExplorerXML {
|
||||
var modified = copy()
|
||||
try modified.set(path, to: newElement)
|
||||
try modified.set(path, to: explorer)
|
||||
return modified
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ public struct ExplorerXML: PathExplorer {
|
|||
public var int: Int? { element.int }
|
||||
public var double: Double? { element.double }
|
||||
|
||||
@available(*, deprecated)
|
||||
@available(*, deprecated, renamed: "double")
|
||||
public var real: Double? { element.double }
|
||||
|
||||
/// Always `nil` on XML
|
||||
|
@ -259,7 +259,7 @@ extension ExplorerXML {
|
|||
func set(value: ValueSetter) {
|
||||
switch value {
|
||||
case .explorerValue(let value): set(newValue: value)
|
||||
case .xmlElement(let element): set(newElement: element)
|
||||
case .explorerXML(let explorer): set(newElement: explorer.element)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,7 +306,7 @@ extension ExplorerXML {
|
|||
/// Wrapper to more easily handle setting an ExplorerValue or Element
|
||||
enum ValueSetter {
|
||||
case explorerValue(ExplorerValue)
|
||||
case xmlElement(Element)
|
||||
case explorerXML(ExplorerXML)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -15,7 +15,9 @@ public struct CodablePathExplorer<Format: CodableFormat>: PathExplorer {
|
|||
public var string: String? { value.string }
|
||||
public var bool: Bool? { value.bool }
|
||||
public var int: Int? { value.int }
|
||||
@available(*, deprecated, renamed: "double")
|
||||
public var real: Double? { value.real }
|
||||
public var double: Double? { value.real }
|
||||
public var data: Data? { value.data }
|
||||
public func array<T>(of type: T.Type) throws -> [T] where T: ExplorerValueCreatable { try value.array(of: type) }
|
||||
public func dictionary<T>(of type: T.Type) throws -> [String: T] where T: ExplorerValueCreatable { try value.dictionary(of: type) }
|
||||
|
|
|
@ -31,6 +31,9 @@ where
|
|||
/// Non `nil` if the key is of the `Double` type
|
||||
var real: Double? { get }
|
||||
|
||||
/// Non `nil` if the key is of the `Double` type
|
||||
var double: Double? { get }
|
||||
|
||||
/// Non `nil` if the key is of the `Data` type
|
||||
var data: Data? { get }
|
||||
|
||||
|
|
|
@ -71,8 +71,8 @@ struct CSVCommand: ParsableCommand {
|
|||
|
||||
} else {
|
||||
var output = try explorer.exportString()
|
||||
let colorInjector = try self.colorInjector(for: dataFormat)
|
||||
output = colorise ? colorInjector.inject(in: output) : output
|
||||
let highlight = try self.colorInjector(for: dataFormat)
|
||||
output = colorise ? highlight(output) : output
|
||||
print(output)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ extension ParsableCommand {
|
|||
|
||||
extension ParsableCommand {
|
||||
|
||||
func colorInjector(for format: Scout.DataFormat) throws -> TextInjector {
|
||||
func colorInjector(for format: Scout.DataFormat) throws -> (String) -> String {
|
||||
switch format {
|
||||
|
||||
case .json:
|
||||
|
@ -51,28 +51,28 @@ extension ParsableCommand {
|
|||
if let colors = try getColorFile()?.json {
|
||||
jsonInjector.delegate = JSONInjectorColorDelegate(colors: colors)
|
||||
}
|
||||
return jsonInjector
|
||||
return jsonInjector.inject
|
||||
|
||||
case .plist:
|
||||
let plistInjector = PlistInjector(type: .terminal)
|
||||
if let colors = try getColorFile()?.plist {
|
||||
plistInjector.delegate = PlistInjectorColorDelegate(colors: colors)
|
||||
}
|
||||
return plistInjector
|
||||
return plistInjector.inject
|
||||
|
||||
case .yaml:
|
||||
let yamlInjector = YAMLInjector(type: .terminal)
|
||||
if let colors = try getColorFile()?.yaml {
|
||||
yamlInjector.delegate = YAMLInjectorColorDelegate(colors: colors)
|
||||
}
|
||||
return yamlInjector
|
||||
return yamlInjector.inject
|
||||
|
||||
case .xml:
|
||||
let xmlInjector = XMLEnhancedInjector(type: .terminal)
|
||||
if let colors = try getColorFile()?.xml {
|
||||
xmlInjector.delegate = XMLInjectorColorDelegate(colors: colors)
|
||||
}
|
||||
return xmlInjector
|
||||
return xmlInjector.inject
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -126,8 +126,8 @@ extension SADCommand {
|
|||
|
||||
func printOutput(output: String, with format: Scout.DataFormat) throws {
|
||||
if colorise {
|
||||
let injector = try colorInjector(for: format)
|
||||
print(injector.inject(in: output))
|
||||
let highlight = try colorInjector(for: format)
|
||||
print(highlight(output))
|
||||
} else {
|
||||
print(output)
|
||||
}
|
||||
|
|
|
@ -75,13 +75,13 @@ struct ReadCommand: PathExplorerInputCommand, ExportCommand {
|
|||
print(value)
|
||||
|
||||
case .noExport:
|
||||
let colorInjector = try self.colorInjector(for: P.format)
|
||||
let output = colorise ? colorInjector.inject(in: value) : value
|
||||
let highlight = try self.colorInjector(for: P.format)
|
||||
let output = colorise ? highlight(value) : value
|
||||
print(output)
|
||||
|
||||
case .dataFormat(let format):
|
||||
let colorInjector = try self.colorInjector(for: format)
|
||||
let output = colorise ? colorInjector.inject(in: value) : value
|
||||
let highlight = try self.colorInjector(for: format)
|
||||
let output = colorise ? highlight(value) : value
|
||||
print(output)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue