論証
20658 ワード
コマンドラインツールの引数を解析するいくつかの機能的ヘルパーを提供することを目的とした迅速な遊び場.それはOvertureを使用して、高い作曲性、柔軟性と進化するプロジェクトの自由に少しの影響のために構築されています.
中央使用例はArchery sであった.実際に解釈された議論だけが消費される.他のいずれかを収集する(
すべての例を使用します.
次は何ですか.
同様の概念はプロセス、特に割り込みの処理にも適用できる.
中央使用例はArchery sであった.実際に解釈された議論だけが消費される.他のいずれかを収集する(
remaining
)または実行を防ぐ必要があります(exhaust
)、現在のコマンドに応じて.すべての例を使用します.
// Experiment
do {
let (isVerbose, whoToGreet, language, _) = try with(["-v", "hi", "Some string", "--language", "en"], chain(
flag("verbose", "v"),
positional("Name"),
argument("language", "l"),
exhaust
))
} catch {
print("Command failed:", error)
}
マイクロライブラリ自体の実装// Errors
private func quoted(_ string: String) -> String {
return "\"\(string)\""
}
public protocol StringConvertibleError: Error, CustomStringConvertible {}
public struct MissingArgumentError: StringConvertibleError {
public let name: String?
public var description: String {
return with(name, pipe(
map(quoted),
map { "Missing argument \($0)" },
??"Missing argument"
))
}
}
public struct NonExhaustiveArgumentsError: StringConvertibleError {
public let remaining: [String]
public var description: String {
return "Unused arguments: \(remaining)"
}
}
// Domain
private func isArgument(named name: String) -> (String) -> Bool {
return { $0 == "-\(name)" || $0 == "--\(name)" }
}
private func isOneArgument(of names: [String]) -> (String) -> Bool {
return { passed in
names.lazy
.map(isArgument(named:))
.reduce(false, { $0 || $1(passed) })
}
}
private func indexOfArguments(named names: [String]) -> ([String]) -> Array<String>.Index? {
return { passed in
passed.index(where: isOneArgument(of: names))
}
}
public func flag(_ names: String...) -> ([String]) -> ([String], Bool) {
return { arguments in
if let index = arguments.index(where: isOneArgument(of: names)) {
var result = arguments
result.remove(at: index)
return (result, true)
} else {
return (arguments, false)
}
}
}
public func positional(_ name: String? = nil) -> ([String]) throws -> ([String], String) {
return { arguments in
let index = arguments.index(where: { !$0.starts(with: "-")})
if let index = index {
var result = arguments
result.remove(at: index)
return (result, arguments[index])
} else {
throw MissingArgumentError(name: name)
}
}
}
public func optional<A>(_ f: @escaping ([String]) throws -> ([String], A)) -> ([String]) throws -> ([String], A?) {
return { arguments in
do {
let (remaining, parsed) = try f(arguments)
return (remaining, .some(parsed))
} catch is MissingArgumentError {
return (arguments, nil)
} catch {
throw error
}
}
}
public func argument(_ names: String...) -> ([String]) throws -> ([String], String) {
return { arguments in
if let flagIndex = indexOfArguments(named: names)(arguments), arguments.count >= flagIndex + 2 {
let value = arguments[flagIndex + 1]
var rest = arguments
rest.remove(at: flagIndex + 1)
rest.remove(at: flagIndex)
return (rest, value)
} else {
throw MissingArgumentError(name: names.first)
}
}
}
public func exhaust(_ arguments: [String]) throws -> ([String], Void) {
if arguments.isEmpty {
return ([], ())
} else {
throw NonExhaustiveArgumentsError(remaining: arguments)
}
}
public func remaining(_ arguments: [String]) -> ([String], [String]) {
return ([], arguments)
}
次は何ですか.
同様の概念はプロセス、特に割り込みの処理にも適用できる.
with(Process(), concat(
setWorkingDir("tmp"),
passInterrupt(),
setBashCommand("") // is { concat(setLaunchPath("/bin/bash"), setArguments(["-c", $0]) }
))
Reference
この問題について(論証), 我々は、より多くの情報をここで見つけました https://dev.to/vknabel/argumentoverture-44o8テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol