All Projects â†’ JohnSundell â†’ Identity

JohnSundell / Identity

Licence: mit
🆔 Type-safe identifiers in Swift

Programming Languages

swift
15916 projects

Projects that are alternatives of or similar to Identity

regbits
C++ templates for type-safe bit manipulation
Stars: ✭ 53 (-81.21%)
Mutual labels:  type-safety
genTypeScript
Auto generation of type-safe bindings between Reason and Typescript.
Stars: ✭ 75 (-73.4%)
Mutual labels:  type-safety
typed
Typed variables for PHP 7.4+ ( don't use this please )
Stars: ✭ 66 (-76.6%)
Mutual labels:  type-safety
tsafe
🔩 The missing TypeScript utils
Stars: ✭ 285 (+1.06%)
Mutual labels:  type-safety
yants
Yet Another Nix Type System | Source has moved to https://git.tazj.in/tree/nix/yants
Stars: ✭ 35 (-87.59%)
Mutual labels:  type-safety
HashedExpression
Type-safe modelling DSL, symbolic transformation, and code generation for solving optimization problems.
Stars: ✭ 40 (-85.82%)
Mutual labels:  type-safety
Unchained
A fully type safe, compile time only units library.
Stars: ✭ 70 (-75.18%)
Mutual labels:  type-safety
Cone
Cone Programming Language
Stars: ✭ 257 (-8.87%)
Mutual labels:  type-safety
typical
Data interchange with algebraic data types.
Stars: ✭ 114 (-59.57%)
Mutual labels:  type-safety
llvm-hs-typed
Type Safe LLVM IR ( Experimental )
Stars: ✭ 47 (-83.33%)
Mutual labels:  type-safety
PolyCast
Safely cast values to int, float, or string in PHP
Stars: ✭ 52 (-81.56%)
Mutual labels:  type-safety
playwarts
WartRemover warts for Play Framework.
Stars: ✭ 23 (-91.84%)
Mutual labels:  type-safety
eslint-plugin-total-functions
An ESLint plugin to enforce the use of total functions (and prevent the use of partial functions) in TypeScript.
Stars: ✭ 72 (-74.47%)
Mutual labels:  type-safety
vault
A typed, persistent store for values of arbitrary types
Stars: ✭ 55 (-80.5%)
Mutual labels:  type-safety
postgresql-typed
Haskell PostgreSQL library with compile-time type inference
Stars: ✭ 72 (-74.47%)
Mutual labels:  type-safety
kanji
A strongly typed GraphQL API framework
Stars: ✭ 12 (-95.74%)
Mutual labels:  type-safety
type-lite
type - Strong types for C++98, C++11 and later in a single-file header-only library
Stars: ✭ 25 (-91.13%)
Mutual labels:  type-safety
Dry Struct
Typed struct and value objects
Stars: ✭ 263 (-6.74%)
Mutual labels:  type-safety
nest-typed-config
Intuitive, type-safe configuration module for Nest framework ✨
Stars: ✭ 47 (-83.33%)
Mutual labels:  type-safety
coalton
Coalton is an efficient, statically typed functional programming language that supercharges Common Lisp.
Stars: ✭ 439 (+55.67%)
Mutual labels:  type-safety

🆔 Identity

Welcome to Identity, a small library that makes it easy to create type-safe identifiers in Swift. Identifiers are often core to how models and other values are referenced within a code base, so leveraging the compiler to ensure that they're used in a correct manner can go a long way to making the model layer of an app or system more robust.

For more information, check out "Type-safe identifiers in Swift" on Swift by Sundell.

Making types identifiable

All you have to do to use Identity is to make a model conform to Identifiable, and give it an id property, like this:

struct User: Identifiable {
    let id: Identifier<User>
    let name: String
}

And just like that, the above User identifier is now type-safe! Thanks to Swift’s type inference capabilities, it’s also possible to implement an Identifiable type’s id simply by using ID as its type:

struct User: Identifiable {
    let id: ID
    let name: String
}

The ID type alias is automatically added for all Identifiable types, which also makes it possible to refer to Identifier<User> as User.ID.

Customizing the raw type

Identifier values are backed by strings by default, but that can easily be customized by giving an Identifiable type a RawIdentifier:

struct Article: Identifiable {
    typealias RawIdentifier = UUID

    let id: ID
    let title: String
}

The above Article identifier is now backed by a UUID instead of a String.

Conveniences built-in

Even though Identity is focused on type safety, it still offers several conveniences to help reduce verbosity. For example, if an Identifier is backed by a raw value type that can be expressed by a String literal, so can the identifier:

let user = User(id: "johnsundell", name: "John Sundell")

The same is also true for identifiers that are backend by a raw value type that can be expressed by Int literals:

let tag = Tag(id: 7, name: "swift")

Identifier also becomes Codable, Hashable and Equatable whenever its raw value type conforms to one of those protocols.

Type safety

So how exactly does Identity make identifiers more type-safe? First, when using Identity, it no longer becomes possible to accidentally pass an identifier for one type to an API that accepts an identifier for another type. For example, this code won't compile when using Identity:

articleManager.article(withID: user.id)

The compiler will give us an error above, since we're trying to pass an Identifier<User> value to a method that accepts an Identifier<Article> - giving us much stronger type safety than when using plain values, like String or Int, as identifiers.

Identity also makes it impossible to accidentally declare id properties of the wrong type. So the following won't compile either:

struct User: Identifiable {
    let id: Identifier<Article>
}

The reason the above code will fail to compile is because Identifiable requires types conforming to it to declare identifiers that are bound to the same type as the conformer, again providing an extra level of type safety.

Installation

Since Identity is implemented within a single file, the easiest way to use it is to simply drag and drop it into your Xcode project.

But if you wish to use a dependency manager, you can use the Swift Package Manager by declaring Identity as a dependency in your Package.swift file:

.package(url: "https://github.com/JohnSundell/Identity", from: "0.1.0")

For more information, see the Swift Package Manager documentation.

Contributions & support

Identity is developed completely in the open, and your contributions are more than welcome.

Before you start using Identity in any of your projects, it’s highly recommended that you spend a few minutes familiarizing yourself with its documentation and internal implementation (it all fits in a single file!), so that you’ll be ready to tackle any issues or edge cases that you might encounter.

To learn more about the principles used to implement Identity, check out "Type-safe identifiers in Swift" on Swift by Sundell.

This project does not come with GitHub Issues-based support, and users are instead encouraged to become active participants in its continued development — by fixing any bugs that they encounter, or improving the documentation wherever it’s found to be lacking.

If you wish to make a change, open a Pull Request — even if it just contains a draft of the changes you’re planning, or a test that reproduces an issue — and we can discuss it further from there.

Hope you’ll enjoy using Identity! 😀

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].