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
- Host: GitHub
- URL: https://github.com/stansmida/swift-conformable-existential
- Owner: stansmida
- License: mit
- Created: 2023-11-11T17:57:23.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2025-09-16T10:22:28.000Z (9 months ago)
- Last Synced: 2025-10-18T09:55:18.640Z (8 months ago)
- Topics: codable, existential, hashable, swift
- Language: Swift
- Homepage: http://stansmida.github.io/swift-conformable-existential/documentation/swiftconformableexistential
- Size: 475 KB
- Stars: 4
- Watchers: 1
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
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`