Export 1-dimension arrays and dicts to Zsh
Export arrays to Zsh arrays and dictionaries to Zsh associate arrays.
This commit is contained in:
parent
8132bcbe0b
commit
2912e48c86
|
@ -98,7 +98,7 @@ public extension ExplorerError {
|
|||
}
|
||||
|
||||
static func mismatchingType<T>(_ type: T.Type, value: ExplorerValue) -> Self {
|
||||
ExplorerError(description: "ExplorerValue \(value) cannot be represented as \(T.self)")
|
||||
ExplorerError(description: "ExplorerValue '\(value)' cannot be represented as \(T.self)")
|
||||
}
|
||||
|
||||
static func predicateNotEvaluatable(_ predicate: String, description: String) -> Self {
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
import ArgumentParser
|
||||
import Scout
|
||||
import ScoutCLTCore
|
||||
import Foundation
|
||||
|
||||
struct AddCommand: SADCommand {
|
||||
|
||||
|
@ -44,7 +43,7 @@ struct AddCommand: SADCommand {
|
|||
var csvSeparator: String?
|
||||
|
||||
@Option(name: .export, help: .export)
|
||||
var exportFormat: Scout.DataFormat?
|
||||
var exportFormat: ExportFormat?
|
||||
|
||||
// MARK: - Functions
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import ArgumentParser
|
||||
import Scout
|
||||
import Foundation
|
||||
import ScoutCLTCore
|
||||
|
||||
struct DeleteCommand: SADCommand {
|
||||
|
||||
|
@ -46,7 +46,7 @@ struct DeleteCommand: SADCommand {
|
|||
var csvSeparator: String?
|
||||
|
||||
@Option(name: .export, help: .export)
|
||||
var exportFormat: Scout.DataFormat?
|
||||
var exportFormat: ExportFormat?
|
||||
|
||||
// MARK: - Functions
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// Copyright (c) 2020-present Alexis Bridoux
|
||||
// MIT license, see LICENSE file for details
|
||||
|
||||
import Foundation
|
||||
import ScoutCLTCore
|
||||
import Scout
|
||||
import ArgumentParser
|
||||
|
||||
|
@ -51,7 +51,7 @@ struct DeleteKeyCommand: SADCommand {
|
|||
var csvSeparator: String?
|
||||
|
||||
@Option(name: [.short, .customLong("export")], help: "Convert the data to the specified format")
|
||||
var exportFormat: Scout.DataFormat?
|
||||
var exportFormat: ExportFormat?
|
||||
|
||||
// MARK: - Functions
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import Foundation
|
|||
import ArgumentParser
|
||||
import Scout
|
||||
import Lux
|
||||
import ScoutCLTCore
|
||||
|
||||
extension ParsableCommand {
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ protocol PathExplorerInputCommand: ParsableCommand {
|
|||
/// A file path from which to read and write the data
|
||||
var modifyFilePath: String? { get }
|
||||
|
||||
/// The data format to use to read the data
|
||||
var dataFormat: Scout.DataFormat { get }
|
||||
|
||||
/// Called with the correct `PathExplorer` when `inferPathExplorer(from:in:)` completes
|
||||
|
|
|
@ -49,7 +49,7 @@ extension SADCommand {
|
|||
|
||||
extension SADCommand {
|
||||
|
||||
/// Print the data from the path explorer and colorize it if specified
|
||||
/// Print the data from the path explorer and highlight it if specified
|
||||
/// - Parameters:
|
||||
/// - outputFilePath: A file path to a file where to write the data
|
||||
/// - pathExplorer: The path explorer to use to get the data
|
||||
|
@ -84,6 +84,26 @@ extension SADCommand {
|
|||
}
|
||||
return
|
||||
|
||||
case .array:
|
||||
do {
|
||||
let array = try pathExplorer.array(of: GroupExportValue.self).map(\.value).joined(separator: " ")
|
||||
print("\(array)")
|
||||
|
||||
} catch {
|
||||
throw RuntimeError.custom("Unable to represent the value as an array of single elements")
|
||||
}
|
||||
|
||||
case .dictionary:
|
||||
do {
|
||||
let dict = try pathExplorer.dictionary(of: GroupExportValue.self)
|
||||
.map { "\($0.key) \($0.value.value)" }
|
||||
.joined(separator: " ")
|
||||
print("\(dict)")
|
||||
|
||||
} catch {
|
||||
throw RuntimeError.custom("Unable to represent the value as a dictionary of single elements")
|
||||
}
|
||||
|
||||
case .noExport:
|
||||
break
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ struct ReadCommand: PathExplorerInputCommand, ExportCommand {
|
|||
var csvSeparator: String?
|
||||
|
||||
@Option(name: .export, help: .export)
|
||||
var exportFormat: Scout.DataFormat?
|
||||
var exportFormat: ExportFormat?
|
||||
|
||||
// MARK: - Functions
|
||||
|
||||
|
@ -60,7 +60,6 @@ struct ReadCommand: PathExplorerInputCommand, ExportCommand {
|
|||
let readingPath = self.readingPath ?? Path()
|
||||
var explorer = try pathExplorer.get(readingPath)
|
||||
let value = try getValue(from: &explorer)
|
||||
let colorInjector = try self.colorInjector(for: exportFormat ?? P.format)
|
||||
|
||||
if value == "" {
|
||||
throw RuntimeError.noValueAt(path: readingPath.description)
|
||||
|
@ -71,8 +70,15 @@ struct ReadCommand: PathExplorerInputCommand, ExportCommand {
|
|||
return
|
||||
}
|
||||
|
||||
let output = colorise ? colorInjector.inject(in: value) : value
|
||||
print(output)
|
||||
switch try exportOption() {
|
||||
case .array, .dictionary, .noExport, .csv: // cases already handled in getValue()
|
||||
print(value)
|
||||
|
||||
case .dataFormat(let format):
|
||||
let colorInjector = try self.colorInjector(for: format)
|
||||
let output = colorInjector.inject(in: value)
|
||||
print(output)
|
||||
}
|
||||
}
|
||||
|
||||
func getValue<Explorer: SerializablePathExplorer>(from explorer: inout Explorer) throws -> String {
|
||||
|
@ -85,6 +91,26 @@ struct ReadCommand: PathExplorerInputCommand, ExportCommand {
|
|||
case .dataFormat(let format):
|
||||
return try explorer.exportString(to: format, rootName: fileName(of: inputFilePath))
|
||||
|
||||
case .array:
|
||||
do {
|
||||
let array = try explorer.array(of: GroupExportValue.self).map(\.value).joined(separator: " ")
|
||||
return "\(array)"
|
||||
|
||||
} catch {
|
||||
throw RuntimeError.custom("Unable to represent the value as an array of single elements")
|
||||
}
|
||||
|
||||
case .dictionary:
|
||||
do {
|
||||
let dict = try explorer.dictionary(of: GroupExportValue.self)
|
||||
.map { "\($0.key) \($0.value.value)" }
|
||||
.joined(separator: " ")
|
||||
return "\(dict)"
|
||||
|
||||
} catch {
|
||||
throw RuntimeError.custom("Unable to represent the value as an array of single elements")
|
||||
}
|
||||
|
||||
case .noExport:
|
||||
break
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ struct SetCommand: SADCommand {
|
|||
var csvSeparator: String?
|
||||
|
||||
@Option(name: .export, help: .export)
|
||||
var exportFormat: Scout.DataFormat?
|
||||
var exportFormat: ExportFormat?
|
||||
|
||||
// MARK: - Functions
|
||||
|
||||
|
|
|
@ -9,12 +9,14 @@ import Scout
|
|||
public enum Export: Equatable {
|
||||
case noExport
|
||||
case csv(separator: String)
|
||||
case dataFormat(format: Scout.DataFormat)
|
||||
case dataFormat(format: DataFormat)
|
||||
case array
|
||||
case dictionary
|
||||
}
|
||||
|
||||
public protocol ExportCommand {
|
||||
var csvSeparator: String? { get }
|
||||
var exportFormat: DataFormat? { get }
|
||||
var exportFormat: ExportFormat? { get }
|
||||
}
|
||||
|
||||
public extension ExportCommand {
|
||||
|
@ -22,7 +24,15 @@ public extension ExportCommand {
|
|||
func exportOption() throws -> Export {
|
||||
switch (csvSeparator, exportFormat) {
|
||||
case (let separator?, nil): return .csv(separator: separator)
|
||||
case (nil, let format?): return .dataFormat(format: format)
|
||||
case (nil, let format?):
|
||||
switch format {
|
||||
case .array: return .array
|
||||
case .dict: return .dictionary
|
||||
case .json: return .dataFormat(format: .json)
|
||||
case .plist: return .dataFormat(format: .plist)
|
||||
case .yaml: return .dataFormat(format: .yaml)
|
||||
case .xml: return .dataFormat(format: .xml)
|
||||
}
|
||||
case (nil, nil): return .noExport
|
||||
case (.some, .some): throw CLTCoreError.exportConflict
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
//
|
||||
// Scout
|
||||
// Copyright (c) 2020-present Alexis Bridoux
|
||||
// MIT license, see LICENSE file for details
|
||||
|
||||
import ArgumentParser
|
||||
import Scout
|
||||
|
||||
/// Models the value the export process can take
|
||||
public enum ExportFormat: String, CaseIterable, ExpressibleByArgument, Equatable {
|
||||
case json, plist, yaml, xml, array, dict
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// Scout
|
||||
// Copyright (c) 2020-present Alexis Bridoux
|
||||
// MIT license, see LICENSE file for details
|
||||
|
||||
import Foundation
|
||||
import Scout
|
||||
|
||||
/// Type serving only the purpose to map dictionaries or arrays
|
||||
/// returned by a `PathExplorer` to a `String` value.
|
||||
///
|
||||
/// Init throws if the value is not single.
|
||||
public struct GroupExportValue: ExplorerValueCreatable {
|
||||
|
||||
public let value: String
|
||||
|
||||
public init(from explorerValue: ExplorerValue) throws {
|
||||
switch explorerValue {
|
||||
case .string(let string): value = string
|
||||
case .int(let int): value = int.description
|
||||
case .double(let double): value = double.description
|
||||
case .bool(let bool): value = bool.description
|
||||
case .data(let data): value = data.base64EncodedString()
|
||||
case .date(let date): value = date.description
|
||||
case .dictionary: throw CLTCoreError.wrongUsage("Trying to export a dictionary of values that are not single")
|
||||
case .array: throw CLTCoreError.wrongUsage("Trying to export an array of values that are not single")
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue