|  | import SwiftUI | 
        
          |  |  | 
        
          |  | struct UnwrappingButton<Label: View, T>: View { | 
        
          |  |  | 
        
          |  | enum Unwrapping<T> { | 
        
          |  | case element(value: T?, action: (T) -> Void) | 
        
          |  | case binding(value: Binding<T?>, action: (Binding<T>) -> Void) | 
        
          |  |  | 
        
          |  | var value: T? { | 
        
          |  | switch self { | 
        
          |  | case .element(let value, _): | 
        
          |  | return value | 
        
          |  | case .binding(let value, _): | 
        
          |  | return value.wrappedValue | 
        
          |  | } | 
        
          |  | } | 
        
          |  |  | 
        
          |  | func run() { | 
        
          |  | switch self { | 
        
          |  | case .element(let value, let action): | 
        
          |  | if let value = value { | 
        
          |  | action(value) | 
        
          |  | } | 
        
          |  | case .binding(let value, let action): | 
        
          |  | if let value = Binding(value) { | 
        
          |  | action(value) | 
        
          |  | } | 
        
          |  | } | 
        
          |  | } | 
        
          |  | } | 
        
          |  |  | 
        
          |  | let unwrapping: Unwrapping<T> | 
        
          |  | @ViewBuilder let label: Label | 
        
          |  |  | 
        
          |  | init(element: T?, action: @escaping (T) -> Void, @ViewBuilder label: () -> Label) { | 
        
          |  | self.unwrapping = .element(value: element, action: action) | 
        
          |  | self.label = label() | 
        
          |  | } | 
        
          |  |  | 
        
          |  | init(element: Binding<T?>, action: @escaping (Binding<T>) -> Void, @ViewBuilder label: () -> Label) { | 
        
          |  | self.unwrapping = .binding(value: element, action: action) | 
        
          |  | self.label = label() | 
        
          |  | } | 
        
          |  |  | 
        
          |  | var body: some View { | 
        
          |  | Button { | 
        
          |  | unwrapping.run() | 
        
          |  | } label: { | 
        
          |  | label | 
        
          |  | } | 
        
          |  | .disabled(unwrapping.value == nil) | 
        
          |  | } | 
        
          |  | } | 
        
          |  |  | 
        
          |  | extension UnwrappingButton where Label == Text { | 
        
          |  | init(element: T?, title: String, action: @escaping (T) -> Void) { | 
        
          |  | self.unwrapping = .element(value: element, action: action) | 
        
          |  | self.label = Text(title) | 
        
          |  | } | 
        
          |  |  | 
        
          |  | init(element: Binding<T?>, title: String, action: @escaping (Binding<T>) -> Void) { | 
        
          |  | self.unwrapping = .binding(value: element, action: action) | 
        
          |  | self.label = Text(title) | 
        
          |  | } | 
        
          |  | } |