swiftenumspreconditions

Asserting a restriction on an associated value in an enum


I have an enum like...

enum Analytics {
  case event(name: String)
  case other1
  case other2
}

But I need to make sure that the name value is no longer than 40 characters.

Is there a way to have some sort of precondition on the value put into the enum? I'm not sure where this would/should exist? If this were a struct I could put a precondition or something in the init but how would I do that for an enum?

Thanks


Solution

  • In Swift, a restriction or refinement of a type can only be put in place using the type system.

    enum Analytics {
      case event(name: String.LimitedTo20Count)
      case other1
      case other2
    }
    
    extension Collection {
      typealias LimitedTo20Count = ModuleName.LimitedTo20Count<Self>
    }
    
    struct LimitedTo20Count<Collection: Swift.Collection> {
      struct Error: Swift.Error { }
      
      init(wrappedValue: Collection) throws {
        guard wrappedValue.count <= 20 else {
          throw Error()
        }
        self.wrappedValue = wrappedValue
      }
    
      let wrappedValue: Collection
    }