An open API service indexing awesome lists of open source software.

https://github.com/stansmida/swift-conformable-existential

Hashable and Codable support for existential types
https://github.com/stansmida/swift-conformable-existential

codable existential hashable swift

Last synced: 8 months ago
JSON representation

Hashable and Codable support for existential types

Awesome Lists containing this project

README

          

# SwiftConformableExistential

A set of Swift Macros designed to facilitate the conformance of existential types to
`Equatable`, `Hashable`, `Decodable`, `Encodable`, and `Codable`.

## Overview

Until Swift gains support for [extending existential types](https://github.com/apple/swift-evolution/blob/main/proposals/0335-existential-any.md#extending-existential-types),
they cannot satisfy generic constraints on their own.

```swift
protocol Drinkable: Hashable {}

// Is ill-formed, because `any Drinkable` does not conform to `Hashable`,
// despite the fact that every `Drinkable` instance does.
struct Foo: Hashable {
let drinkable: any Drinkable
}
```

Overcoming this limitation requires extensive boilerplate code. This package offers a set of macros
that can be attached to your protocol to synthesize ready-to-use property wrappers over the existential
type of the annotated protocol. These wrappers act as proxies for the respective conformances.
```swift
import SwiftConformableExistential

@HashableExistential
protocol Drinkable: Hashable {}

// `HashableDrinkable` is a `Hashable` wrapper over `any Drinkable`,
// synthesized of the attached `@HashableExistential` macro,
// allowing the compiler to now synthesize the `Hashable` implementation for `Foo`.
struct Foo: Hashable {

@HashableDrinkable
var drinkable: any Drinkable
}
```

Alternatively, the wrappers can also be used on-the-fly, particularly in situations where
employing property wrappers is not suitable:

```swift
struct Tap: View {

@State private var drinkable: any Drinkable = .smallBeer

var body: some View {
...
.onChange(of: HashableDrinkable(drinkable)) { _, newValue in
prepareForPouring(newValue.wrappedValue)
}
}
}
```

For more, see [the documentation](http://stansmida.github.io/swift-conformable-existential/documentation/swiftconformableexistential).

## Installation

Via SwiftPM.

In your package dependencies:

`.package(url: "https://github.com/stansmida/swift-conformable-existential.git", from: "0.4.0"),`

And in your target dependencies:

`.product(name: "SwiftConformableExistential", package: "swift-conformable-existential"),`

And don't forget to import in files where annotating your protocols:

`import SwiftConformableExistential`