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

https://github.com/arasan01/swift-dependencies-extras

Libraries that make swift-dependencies even more useful
https://github.com/arasan01/swift-dependencies-extras

macros swift xcode

Last synced: 4 months ago
JSON representation

Libraries that make swift-dependencies even more useful

Awesome Lists containing this project

README

          

# Dependencies Protocol Extras

Library to make swift-dependencies even more useful when using Protocol.

## Table of Contents

- [Dependencies Protocol Extras](#dependencies-protocol-extras)
- [Table of Contents](#table-of-contents)
- [Overview](#overview)
- [Quick start](#quick-start)
- [Documentation](#documentation)
- [Installation](#installation)
- [Now on provide.](#now-on-provide)
- [Dependencies Extras Macros](#dependencies-extras-macros)
- [License](#license)

## Overview

Xcode's support for protocol-oriented declarations and implementations is very strong. However, as we understood in the Point-Free episode, we pay a price for this in exchange for some flexibility. So is there a way to move things forward while getting the benefits of both? Yes, that is macros! Macros allow us to automatically convert protocol-based to struct-based. This is an approach that works very well. By depositing the implementation in the macro, the protocol becomes an entity to be assisted by Xcode, and is internally converted into a function call of the implementation.

This is a library that extends swift-dependencies, swift-dependencies is here.

https://github.com/pointfreeco/swift-dependencies

## Quick start

Look at this first. Swift The power of Macro makes it possible to cut out and rewrite a single function, even if it is implemented in a protocol.

```swift
import DependenciesExtrasMacros
import Foundation

@DependencyProtocolClient(implemented: ProtocolPersistentImpl.self)
protocol ProtocolPersistent: Sendable {
func load(_ url: URL) throws -> Data
func save(_ data: Data, _ url: URL) async throws -> Void
}

public final class ProtocolPersistentImpl: @unchecked Sendable, ProtocolPersistent {
func load(_ url: URL) throws -> Data { try Data(contentsOf: url) }
func save(_ data: Data, _ url: URL) async throws -> Void { try data.write(to: url) }
}

extension DependencyValues {
#DependencyValueRegister(of: ProtocolPersistent.self, into: "protocolPersistent")
}

struct Runner {
@Dependency(\.protocolPersistent) var protocolPersistent

func run() async throws {
do {
let new = withDependencies {
$0.protocolPersistent.save = { data, url in debugPrint(data, url) }
} operation: {
protocolPersistent
}
try await new.save("struct".data(using: .utf8)!, URL.documentsDirectory.appendingPathComponent(UUID().uuidString, conformingTo: .text))
}
}
}
```

The first step is to give the already existing protocol a macro that informs the world that this will be used for dependency resolution.

```diff
+ @DependencyProtocolClient(implemented: ProtocolPersistentImpl.self)
protocol ProtocolPersistent: Sendable {
func load(_ url: URL) throws -> Data
func save(_ data: Data, _ url: URL) async throws -> Void
}
```

Next, register a structure in DependencyValues that conforms to the DependencyKey generated by the macro

```diff
+ extension DependencyValues {
+ #DependencyValueRegister(of: ProtocolPersistent.self, into: "protocolPersistent")
+ }
```

This ends the need for us to be hands on! This is the only way things will start to work. If it doesn't work or has behavior you don't expect, please give us feedback. We welcome your contribution!

## Documentation

The latest documentation for the Dependencies APIs is available [here][docs].

## Installation

You can add Dependencies to an Xcode project by adding it to your project as a package.

> https://github.com/arasan01/swift-dependencies-extras

If you want to use Dependencies in a [SwiftPM](https://swift.org/package-manager/) project, it's as
simple as adding it to your `Package.swift`:

``` swift
dependencies: [
.package(url: "https://github.com/arasan01/swift-dependencies-extras", from: "0.1.0")
]
```

And then adding the product to any target that needs access to the library:

```swift
.product(name: "DependenciesExtrasMacros", package: "swift-dependencies-extras"),
```

## Now on provide.

### Dependencies Extras Macros

Automatically rewrite the conventional design consisting of Protocol, Class, and Struct based on swift-dependencies in PointFree style, allowing rewriting of each implemented function one by one.

## License

This library is released under the MIT license. See [LICENSE](LICENSE) for details.

[docs]: https://swiftpackageindex.com/arasan01/swift-dependencies-extras/main/documentation/dependenciesextrasmacros