Contents

CaptureContext/swift-hashed

Hashable wrapper type and a set of explicit hashing strategies

Table of Contents

- Features - Predefined comparators - Installation - Basic - Recommended - License

Motivation

Swift strongly encourages Hashable, especially when working with collections, diffing, and identity-based logic.

In practice, however, hashing often becomes problematic at API boundaries:

  • values erased to any
  • reference types without stable identity
  • types you don’t own
  • generic code that cannot add Hashable constraints
  • contexts where different hashing strategies are required

This is especially visible when working with KeyPath-based APIs, where generic composition frequently destroys compile-time Hashable conformance.

Features

Hashed is a lightweight Hashable container that lets you define equality explicitly, while keeping call sites terse.

Predefined hashers

Choose how two values should be compared using a Hashed.Hasher:

Automatic

The detectHashable comparator attempts to cast values to any Hashable and compare them using native hash(into hasher: inout Swift.Hasher) method:

.detectHashable(fallback: Hasher = .dump)

If hashable cast is not possible, the provided fallback hasher is used.

Building blocks
  • .empty – nothing is combined into Swift.Hasher`
  • .custom((Value, inout Swift.Hasher) -> Void) – full control
  • .dump – hashes the textual dump() output
Hashable-driven
  • .defaultHashable – equivalent to using native hash(into hasher: Swift.Hasher) method
Property-based

The property hashable hashes values by a derived hashable projection:

.property(\.someHashableProperty)
.property { String(reflecting: $0) }
  • .objectID – hash reference identity (only when Value: AnyObject)
Error convenience

The .localizedDescription hasher is equivalent to .property(\.localizedDescription).

It is typically most useful as a fallback, for example:

.detectHashable(fallback: .localizedDescription)
Concurrency escape hatches
  • .uncheckedSendable((Value) -> any Hashable)

A property-style comparator for non-sendable projections

  • .uncheckedSendable((Value, inout Swift.Hasher) -> Void)

A custom-style comparator for non-sendable values

[!NOTE]

Most users should prefer .detectHashable() or .property hashers

Installation

Basic

You can add swift-hashed to an Xcode project by adding it as a package dependency.

  1. From the File menu, select Swift Packages › Add Package Dependency…
  2. Enter "https://github.com/capturecontext/swift-hashed" into the package repository URL text field
  3. Choose products you need to link to your project.

Recommended

If you use SwiftPM for your project structure, add swift-hashed dependency to your package file

.package(
  url: "https://github.com/capturecontext/swift-hashed.git", 
  .upToNextMinor("0.0.5")
)

Do not forget about target dependencies

.product(
  name: "Hashed", 
  package: "swift-hashed"
)

License

This library is released under the MIT license. See LICENSE for details.

Package Metadata

Repository: CaptureContext/swift-hashed

Stars: 0

Forks: 0

Open issues: 0

Default branch: main

Primary language: swift

License: MIT

Topics: foundation, hashable, swift

README: README.md