Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use with Codable would be fantastic use case for this library #11

Open
kdawgwilk opened this issue Feb 9, 2018 · 13 comments
Open

Use with Codable would be fantastic use case for this library #11

kdawgwilk opened this issue Feb 9, 2018 · 13 comments

Comments

@kdawgwilk
Copy link

Being able to parse args in a type safe way using Codable would be amazing.

@kovpas
Copy link
Contributor

kovpas commented Feb 9, 2018

Could you please elaborate on this? I'm not sure how exactly this would look like.

@kdawgwilk
Copy link
Author

Yeah sorry I was working on a CLI in go and found this Swift version and thought adding support for decoding the args into a struct using the new Codable APIs like go does would be awesome and keep things type safe. https://github.com/docopt/docopt.go/blob/master/README.md#api

I will try to get a prototype posted here in the next few days to give more detail

@kdawgwilk
Copy link
Author

let doc : String = """
Naval Fate.

Usage:
  naval_fate ship new <name>...
  naval_fate ship <name> move <x> <y> [--speed=<kn>]
  naval_fate ship shoot <x> <y>
  naval_fate mine (set|remove) <x> <y> [--moored|--drifting]
  naval_fate -h | --help
  naval_fate --version

Options:
  -h --help     Show this screen.
  --version     Show version.
  --speed=<kn>  Speed in knots [default: 10].
  --moored      Moored (anchored) mine.
  --drifting    Drifting mine.
"""

struct CommandArgs: Codable {
    enum CodingKeys: String, CodingKey {
        case name = "<name>"
        case x = "<x>"
        case y = "<y>"
        case knots = "<kn>"
        case moored = "--moored"
        case drifting = "--drifting"
    }
    let name: String
    let x: Int
    let y: Int
    let knots: Int
    let moored: Bool
    let drifting: Bool
}

var args = Process.arguments
args.removeAtIndex(0) // arguments[0] is always the program_name
let result = Docopt.decode(CommandArgs.self, args, help: true, version: "1.0")

@kovpas
Copy link
Contributor

kovpas commented Feb 12, 2018

Hmmm, this looks super-interesting. Let me think how to implement this. Please let me know if you already have ideas.

@kdawgwilk
Copy link
Author

The best way would prob be to create a DocoptDecoder similar to how Foundation provides a JSONDecoder

let decoder = DocoptDecoder()
let result = decoder.decode(CommandArgs.self, usageString)

@kovpas
Copy link
Contributor

kovpas commented Feb 12, 2018

I don't have much experience with that, and most of the examples I found are using standard JSONDecoder. I've got a feeling, that decoding a Dictionary into a custom struct should be something more or less standard, but couldn't find anything yet. I'll take some time over the weekend and have a look if such a decoder is easy to implement.

Also - if you have some time and thoughts on how to do that, I'd highly appreciate any input :)

@kdawgwilk
Copy link
Author

@samdeane
Copy link
Contributor

samdeane commented Mar 8, 2018

You could achieve this fairly easily with DictionaryCoding.

Adding the ability to docopt itself would mean adding a dependency, but you could just import it and DictionaryCoding to your client project and then hook them up.

@kovpas
Copy link
Contributor

kovpas commented Mar 9, 2018

Wow, that is something new, thanks a lot, @samdeane! I wouldn't mind having a dependency on DictionaryCoding. One thing that stops me is that Docopt supports cocoapods, while DictionaryCoding doesn't... Copying the source altogether might be a solution, but I'd rather not to do that since updating it would be a pain.

@kdawgwilk
Copy link
Author

Why does docopt support CocoaPods? I can’t think of a case where you would need to parse CLI arguments in an app. SPM seems like the only one that should be needed

@kovpas
Copy link
Contributor

kovpas commented Mar 10, 2018

@kdawgwilk cocoapods is just a way of managing dependencies and creating a project with those dependencies. You can use it for OS X apps as well. When I wrote this library, SPM didn't exist, so cocoapods was the easiest way of adding docopt.swift into projects.

@samdeane
Copy link
Contributor

I've added myself an issue to add pods support to DictionaryCoding (elegantchaos/DictionaryCoding#9). I've never used it myself, but it shouldn't be too tricky by the look of things...

@kovpas
Copy link
Contributor

kovpas commented Mar 11, 2018

Thanks, @samdeane! It is fairly straightforward indeed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants