blob: 2ce0f4fb54f87d617003e15f8e78c4f42753d8e8 [file] [log] [blame]
public struct CommandLineArguments {
public struct MissingArgumentError: Error, CustomStringConvertible {
let argName: String
public var description: String {
return "Missing required argument: \(argName)"
}
}
public struct UnkeyedArgumentError: Error, CustomStringConvertible {
let argName: String
public var description: String {
return "Unexpectedly found command line argument \(argName) without a key"
}
}
private let args: [String: String]
public static func parse<T: Sequence>(_ args: T) throws -> CommandLineArguments
where T.Element == String {
var parsedArgs: [String: String] = [:]
var currentKey: String? = nil
for arg in args {
if arg.hasPrefix("-") {
// Parse a new key
if let currentKey = currentKey {
// The last key didn't have a value. Just add it with an empty string as
// the value to the parsed args
parsedArgs[currentKey] = ""
}
currentKey = arg
} else {
if let currentKey = currentKey {
parsedArgs[currentKey] = arg
} else {
throw UnkeyedArgumentError(argName: arg)
}
currentKey = nil
}
}
if let currentKey = currentKey {
// The last key didn't have a value. Just add it with an empty string as
// the value to the parsed args
parsedArgs[currentKey] = ""
}
return CommandLineArguments(args: parsedArgs)
}
public subscript(key: String) -> String? {
return args[key]
}
public func getRequired(_ key: String) throws -> String {
if let value = args[key] {
return value
} else {
throw MissingArgumentError(argName: key)
}
}
public func has(_ key: String) -> Bool {
return args[key] != nil
}
}