Skip to content

Commit

Permalink
feat: Inlining and API cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
maximkrouk committed Dec 17, 2023
1 parent c8b689f commit caa1f60
Show file tree
Hide file tree
Showing 15 changed files with 352 additions and 100 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
xcuserdata/
Scripts/.installed
Scripts/.bin
DerivedData
121 changes: 83 additions & 38 deletions Sources/FunctionalBuilder/Builder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,60 +4,68 @@ import FunctionalModification

@dynamicMemberLookup
public struct Builder<Base> {
private var _initialValue: () -> Base
private var _configurator: Configurator<Base>
@usableFromInline
internal var _initialValue: () -> Base

@usableFromInline
internal var _configurator: Configurator<Base>

@inlinable
public var base: Base { _initialValue() }

@inlinable
public func build() -> Base { _configurator.configured(base) }

@inlinable
public func apply() where Base: AnyObject { _ = build() }

/// Applies modification to a new builder, created with a built object.
@inlinable
public func reinforce(
_ transform: @escaping (inout Base) -> Void
) -> Builder {
Builder(build()).set(transform)
}
// /// Applies modification to a new builder, created with a built object.
// @inlinable
// public func reinforce(
// _ transform: @escaping (inout Base) -> Void
// ) -> Builder {
// Builder(build()).set(transform)
// }

/// Applies modification to a new builder, created with a built object, also passes leading parameters to transform function.
@inlinable
public func reinforce<T0>(
_ t0: T0,
_ transform: @escaping (inout Base, T0) -> Void
public func reinforce<each Arg>(
_ args: repeat each Arg,
transform: @escaping (inout Base, repeat each Arg) -> Void
) -> Builder {
reinforce { base in transform(&base, t0) }
Builder(build()).set { base in transform(&base, repeat each args) }
}

/// Applies modification to a new builder, created with a built object, also passes leading parameters to transform function.
@inlinable
public func reinforce<T0, T1>(
_ t0: T0,
t1: T1,
_ transform: @escaping (inout Base, T0, T1) -> Void
) -> Builder {
reinforce { base in transform(&base, t0, t1) }
}
// /// Applies modification to a new builder, created with a built object, also passes leading parameters to transform function.
// @inlinable
// public func reinforce<T0, T1>(
// _ t0: T0,
// t1: T1,
// _ transform: @escaping (inout Base, T0, T1) -> Void
// ) -> Builder {
// reinforce { base in transform(&base, t0, t1) }
// }
//
// /// Applies modification to a new builder, created with a built object, also passes leading parameters to transform function.
// @inlinable
// public func reinforce<T0, T1, T2>(
// _ t0: T0,
// _ t1: T1,
// _ t2: T2,
// _ transform: @escaping (inout Base, T0, T1, T2) -> Void
// ) -> Builder {
// reinforce { base in transform(&base, t0, t1, t2) }
// }

/// Applies modification to a new builder, created with a built object, also passes leading parameters to transform function.
@inlinable
public func reinforce<T0, T1, T2>(
_ t0: T0,
_ t1: T1,
_ t2: T2,
_ transform: @escaping (inout Base, T0, T1, T2) -> Void
) -> Builder {
reinforce { base in transform(&base, t0, t1, t2) }
}

public func combined(with builder: Builder) -> Builder {
Builder(
_initialValue,
_configurator.combined(with: builder._configurator)
)
}

@inlinable
public func combined(with configurator: Configurator<Base>) -> Builder {
Builder(
_initialValue,
Expand All @@ -66,14 +74,16 @@ public struct Builder<Base> {
}

/// Creates a new instance of builder with initial value
@inlinable
public init(_ initialValue: @escaping @autoclosure () -> Base) {
self.init(
initialValue,
Configurator<Base>()
)
}

private init(
@usableFromInline
internal init(
_ initialValue: @escaping () -> Base,
_ configurator: Configurator<Base>
) {
Expand All @@ -82,6 +92,7 @@ public struct Builder<Base> {
}

/// Appends transformation to current configuration
@inlinable
public func set(
_ transform: @escaping (inout Base) -> Void
) -> Builder {
Expand All @@ -91,6 +102,7 @@ public struct Builder<Base> {
)
}

@inlinable
public subscript<Value>(
dynamicMember keyPath: WritableKeyPath<Base, Value>
) -> CallableBlock<Value> {
Expand All @@ -100,6 +112,7 @@ public struct Builder<Base> {
)
}

@inlinable
public subscript<Value>(
dynamicMember keyPath: KeyPath<Base, Value>
) -> NonCallableBlock<Value> {
Expand All @@ -109,6 +122,7 @@ public struct Builder<Base> {
)
}

@inlinable
public subscript<Wrapped, Value>(
dynamicMember keyPath: WritableKeyPath<Wrapped, Value>
) -> CallableBlock<Value?> where Base == Wrapped? {
Expand All @@ -118,6 +132,7 @@ public struct Builder<Base> {
)
}

@inlinable
public subscript<Wrapped, Value>(
dynamicMember keyPath: KeyPath<Wrapped, Value>
) -> NonCallableBlock<Value?> where Base == Wrapped? {
Expand All @@ -131,9 +146,11 @@ public struct Builder<Base> {
extension Builder {
@dynamicMemberLookup
public struct CallableBlock<Value> {
private var _block: NonCallableBlock<Value>
@usableFromInline
internal var _block: NonCallableBlock<Value>

init(
@usableFromInline
internal init(
builder: Builder,
keyPath: FunctionalKeyPath<Base, Value>
) {
Expand All @@ -143,6 +160,7 @@ extension Builder {
)
}

@inlinable
public func callAsFunction(
if condition: Bool,
then thenValue: @escaping @autoclosure () -> Value
Expand All @@ -159,6 +177,7 @@ extension Builder {
)
}

@inlinable
public func scope(_ builder: @escaping (Builder<Value>) -> Builder<Value>) -> Builder {
Builder(
_block.builder._initialValue,
Expand All @@ -171,6 +190,7 @@ extension Builder {
)
}

@inlinable
public func ifLetScope<Wrapped>(
_ builder: @escaping (Builder<Wrapped>) -> Builder<Wrapped>
) -> Builder where Value == Wrapped? {
Expand All @@ -186,6 +206,7 @@ extension Builder {
)
}

@inlinable
public func callAsFunction(
if condition: Bool,
then thenValue: @escaping @autoclosure () -> Value,
Expand All @@ -205,6 +226,7 @@ extension Builder {
)
}

@inlinable
public func callAsFunction(_ value: @escaping @autoclosure () -> Value) -> Builder {
Builder(
_block.builder._initialValue,
Expand All @@ -214,18 +236,20 @@ extension Builder {
)
}

@inlinable
public func set(_ transform: @escaping (inout Value) -> Void) -> Builder {
Builder(
_block.builder._initialValue,
_block.builder._configurator.appendingConfiguration { base in
_block.keyPath.embed(
modification(of: _block.keyPath.extract(from: base), with: transform),
reduce(_block.keyPath.extract(from: base), with: transform),
in: base
)
}
)
}

@inlinable
public subscript<LocalValue>(
dynamicMember keyPath: WritableKeyPath<Value, LocalValue>
) -> CallableBlock<LocalValue> {
Expand All @@ -235,12 +259,14 @@ extension Builder {
)
}

@inlinable
public subscript<LocalValue>(
dynamicMember keyPath: KeyPath<Value, LocalValue>
) -> NonCallableBlock<LocalValue> {
_block[dynamicMember: keyPath]
}

@inlinable
public subscript<Wrapped, LocalValue>(
dynamicMember keyPath: WritableKeyPath<Wrapped, LocalValue>
) -> CallableBlock<LocalValue?> where Value == Wrapped? {
Expand All @@ -252,6 +278,7 @@ extension Builder {
)
}

@inlinable
public subscript<Wrapped, LocalValue>(
dynamicMember keyPath: KeyPath<Wrapped, LocalValue>
) -> NonCallableBlock<LocalValue?> where Value == Wrapped? {
Expand All @@ -266,9 +293,22 @@ extension Builder {

@dynamicMemberLookup
public struct NonCallableBlock<Value> {
var builder: Builder
var keyPath: FunctionalKeyPath<Base, Value>
@usableFromInline
internal var builder: Builder

@usableFromInline
internal var keyPath: FunctionalKeyPath<Base, Value>

@usableFromInline
internal init(
builder: Builder,
keyPath: FunctionalKeyPath<Base, Value>
) {
self.builder = builder
self.keyPath = keyPath
}

@inlinable
public func scope(
_ builder: @escaping (Builder<Value>) -> Builder<Value>
) -> Builder where Value: AnyObject {
Expand All @@ -283,6 +323,7 @@ extension Builder {
)
}

@inlinable
public func ifLetScope<Wrapped>(
_ builder: @escaping (Builder<Wrapped>) -> Builder<Wrapped>
) -> Builder where Wrapped: AnyObject, Value == Wrapped? {
Expand All @@ -298,6 +339,7 @@ extension Builder {
)
}

@inlinable
public subscript<LocalValue>(
dynamicMember keyPath: ReferenceWritableKeyPath<Value, LocalValue>
) -> CallableBlock<LocalValue> {
Expand All @@ -307,6 +349,7 @@ extension Builder {
)
}

@inlinable
public subscript<LocalValue>(
dynamicMember keyPath: KeyPath<Value, LocalValue>
) -> NonCallableBlock<LocalValue> {
Expand All @@ -316,6 +359,7 @@ extension Builder {
)
}

@inlinable
public subscript<Wrapped, LocalValue>(
dynamicMember keyPath: ReferenceWritableKeyPath<Wrapped, LocalValue>
) -> CallableBlock<LocalValue?> where Value == Wrapped? {
Expand All @@ -327,6 +371,7 @@ extension Builder {
)
}

@inlinable
public subscript<Wrapped, LocalValue>(
dynamicMember keyPath: KeyPath<Wrapped, LocalValue>
) -> NonCallableBlock<LocalValue?> where Value == Wrapped? {
Expand Down
1 change: 1 addition & 0 deletions Sources/FunctionalBuilder/BuilderProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Foundation

public protocol BuilderProvider {}
extension BuilderProvider {
@inlinable
public var builder: Builder<Self> { .init(self) }
}

Expand Down
Loading

0 comments on commit caa1f60

Please sign in to comment.