Home > Enterprise >  Property wrapper: change empty to Optional
Property wrapper: change empty to Optional

Time:02-19

I've created the following extension:

import Foundation

extension Collection {
    /// Returns `nil` if empty
    var nonEmptyValue: Self? {
        isEmpty ? nil : self
    }
}

Now I'd like to make it a property wrapper so I could use it like this:

final class MyClass {
    @NonEmpty
    var string: String? = "test"
}

The idea is that whenever an empty string is assigned to the property, it gets replaced with nil.

Is it even possible to create such a property wrapper (since String? and String are of different type) and how would I go about it?

CodePudding user response:

I'm using your extension:

import Foundation

@propertyWrapper
struct NonEmpty<T: Collection> {
    
    var wrappedValue: T?
    
    init(wrappedValue: T?) {
        self.wrappedValue = wrappedValue?.nonEmptyValue
    }
}

extension Collection {
    /// Returns `nil` if empty
    var nonEmptyValue: Self? {
        isEmpty ? nil : self
    }
}

and the result is just like image below:

enter image description here

CodePudding user response:

Yes, you can create a property wrapper that does this. For example:

@propertyWrapper
struct NonEmpty<C: Collection> {
    var wrappedValue: C? {
        get { privateWrappedValue }
        set { privateWrappedValue = newValue.flatMap { $0.isEmpty ? nil : newValue } }
    }
    
    private var privateWrappedValue: C?
    
    init(wrappedValue: C?) {
        privateWrappedValue = wrappedValue.flatMap { $0.isEmpty ? nil : wrappedValue }
    }
}

Usage:

class MyClass {
    @NonEmpty
    var string: String? = "test"
}
let myClass = MyClass()
print(myClass.string as Any) // Optional("test")

myClass.string = ""
print(myClass.string as Any) // nil

myClass.string = "Non-empty string"
print(myClass.string as Any) // Optional("Non-empty string")

myClass.string = nil
print(myClass.string as Any) // nil
  • Related