Is it possible to use a protocol to require a nested struct?

Is it possible to use a protocol to require a nested struct?

I have a struct like so:

struct DraftsURL {
    static let scheme = "drafts5"
    static let host = "x-callback-url"
    struct actions {
        static let create = "/create"
        static let open = "/open"
        static let get = "/get"
        static let prepend = "/prepend"
        static let append = "/append"
        static let replaceRange = "/replaceRange"
        static let search = "/search"
        static let workspace = "/workspace"
        static let runAction = "/runAction"
        static let dictate = "/dictate"
        static let arrange = "/arrange"
    }
}

I'd like to generalize some of this with a protocol so that other structs can do the same thing. Something like this:

protocol URLBuilder {
    static var scheme: String { get }
    static var host: String { get }
    struct actions { } //Type 'actions' cannot be nested in protocol 'URLBuilder'
}

For my purposes, I just want to require a struct called actions without dictating anything else in the implementation of that struct.

So is it possible to use a protocol to require a nested struct?

Or perhaps am I not doing this in the "right" way? Is this a sign I should be using a class instead?

It sounds like you want associatedtype

1 Like

Why is it a struct with a lowercase plural name instead of an enum named Action though?

If you do what Nevin said, any types will work.

Thank you guys. I’ll try both of those.

So an enum sounds more type safe than just an associatedtype (since associatedtype will accept any type). But I'm still playing around with enums inside of protocols and I haven't figured out how to nest an enum inside a protocol since Types are not allowed to be nested in protocols.

You're allowed to have typealiases inside protocols, so you could do:

enum URLBuilderAction { ... }

protocol URLBuilder {
  typealias Action = URLBuilderAction
  ...
}

Hmm, I'm not sure this works either. If I understand correctly, then with that approach the enum is already statically defined outside of the protocol. With a typealias now that enum is already defined, plus I don't think swift will let me extension the enum.

I'm trying to figure out how to say in the protocol:

"I'd like some enum named Action, but you can fill that enum with whatever you want."

Why does it matter that it's an enum? There's no way to require that, and if you could, there would be nothing you could do with that restriction anyway.

2 Likes

I was trying to implement your advice when you said:

No, you can not create a protocol that requires conforming types to have nested types defined inside of them. Why would you need this? Do you have an example use case?