🔥 사용자 정의 타입 파싱하기

343자
4분

ExpressibleByArgument 프로토콜을 준수하는 모든 타입은 인자와 옵션으로 파싱할 수 있습니다. 표준 라이브러리에 있는 정수형, 부동소수점형, 문자열, 불리언 타입은 이미 ExpressibleByArgument프로토콜을 채택하고 있습니다.

개발자가 직접 만든 사용자 정의 타입도 ExpressibleByArgument를 준수하도록 만들 수 있습니다. init(argument:) 메서드를 구현하면 됩니다:

struct Path: ExpressibleByArgument {
    var pathString: String
 
    // String 인자를 받아 Path 인스턴스를 초기화하는 생성자를 구현합니다.
    init?(argument: String) {
        self.pathString = argument
    }
}
 
struct Example: ParsableCommand {
    // Path 타입의 inputFile 인자를 선언합니다.
    @Argument var inputFile: Path
}
 
swift

문자열 기반 열거형 같은 RawRepresentable 타입일 경우, 라이브러리에서 기본 구현을 제공하므로 개발자는 프로토콜 준수를 선언만 하면 됩니다.

enum ReleaseMode: String, ExpressibleByArgument {
    case debug, release
}
 
struct Example: ParsableCommand {
    // ReleaseMode 타입의 mode 옵션을 선언합니다.
    @Option var mode: ReleaseMode
 
    mutating func run() throws {
        // 선택된 mode 값을 출력합니다.
        print(mode)
    }
}
 
swift

사용자가 커맨드 라인에서 원시 값을 제공하면, 그 값을 개발자가 직접 만든 사용자 정의 타입으로 변환합니다. 이 과정에서 유효한 값만 허용하여 잘못된 입력을 방지할 수 있습니다:

% example --mode release
release
% example --mode future
Error: The value 'future' is invalid for '--mode <mode>'
text

만약 인자나 옵션으로 사용하고 싶은 타입이 ExpressibleByArgument 프로토콜을 채택하지 않는다면, 문자열을 해당 타입으로 변환하는 throwing 클로저인 transform을 제공하는 방법으로 사용할 수 있습니다. 이 방법은 RawRepresentable 프로토콜보다 구현이 복잡하거나, 직접 정의하지 않은 타입을 사용할 때 유용합니다.

enum Format {
    case text
    case other(String)
 
    // String을 받아 Format 값을 반환하는 이니셜라이저를 구현합니다.
    // 잘못된 값이 주어지면 오류를 던집니다.
    init(_ string: String) throws {
        if string == "text" {
            self = .text
        } else {
            self = .other(string)
        }
    }
}
 
struct Example: ParsableCommand {
    // Format.init을 transform 함수로 지정하여 format 인자를 선언합니다.
    @Argument(transform: Format.init)
    var format: Format
}
 
swift

사용자가 해당 타입에 유효하지 않은 값을 제공했다면 transform 함수에서 오류를 던져야 합니다. transform 함수 오류를 사용자 정의하는 방법은 사용자 정의 검증 제공하기를 참고하세요.

이렇게 ExpressibleByArgument 프로토콜과 transform 클로저를 활용하면, 개발자가 정의한 타입을 아주 유연하게 인자와 옵션으로 사용할 수 있습니다. 타입 유효성을 검사하고 파싱 과정을 제어할 수 있게 되죠. 여러분의 커맨드 라인 도구에 꼭 맞는 타입을 정의해 보세요. 사용자에게 더 직관적이고 안전한 인터페이스를 제공할 수 있습니다.