Skip to content

Instantly share code, notes, and snippets.

@AndreyAnt
Created March 16, 2022 10:58
Show Gist options
  • Save AndreyAnt/c8040b1660432303c38596189f3592b6 to your computer and use it in GitHub Desktop.
Save AndreyAnt/c8040b1660432303c38596189f3592b6 to your computer and use it in GitHub Desktop.
//
// FreeFunctions.swift
// IconJob
//
// Created by andrey.antropov on 08.09.2020.
// Copyright © 2020 br. All rights reserved.
//
import Foundation
/**
Wraps method relaying on self in a weak self closure
- parameter object: Weakly referenced object containing the target function.
- parameter method: Function to wrap with `weak`when called
- returns: Wrapped weakify function
*/
public func weakify<Object: AnyObject>(_ object: Object, method: ((Object) -> () -> Void)?) -> (() -> Void) {
return { [weak object] in
guard let object = object else { return }
method?(object)()
}
}
public func weakify<Object: AnyObject, Input>(_ object: Object, method: ((Object) -> (Input) -> Void)?) -> ((Input) -> Void) {
return { [weak object] value in
guard let object = object else { return }
method?(object)(value)
}
}
/// Weakifying two parameters method
/// - Parameters:
/// - object: owner of the weakifying method
/// - method: method which should be called weakly
/// - Returns: closure which calls the method on the object weakly
public func weakify<Object: AnyObject, Input1, Input2>(
_ object: Object,
method: (
(Object) -> ((Input1, Input2) -> Void)
)?
) -> ((Input1, Input2) -> Void) {
return { [weak object] value1, value2 in
guard let object = object else { return }
method?(object)(value1, value2)
}
}
/// Weakifying three parameters method
/// - Parameters:
/// - object: owner of the weakifying method
/// - method: method which should be called weakly
/// - Returns: closure which calls the method on the object weakly
public func weakify<Object: AnyObject, Input1, Input2, Input3>(
_ object: Object,
method: (
(Object) -> ((Input1, Input2, Input3) -> Void)
)?
) -> ((Input1, Input2, Input3) -> Void) {
return { [weak object] value1, value2, value3 in
guard let object = object else { return }
method?(object)(value1, value2, value3)
}
}
public func weakify<Object: AnyObject, Input, Output>(
_ object: Object,
mappingFunction: @escaping (Input) -> Output,
method: (
(Object) -> ((Output) -> Void)
)?
) -> ((Input) -> Void) {
return { [weak object] value in
guard let object = object else { return }
let mappedValue = mappingFunction(value)
method?(object)(mappedValue)
}
}
/// Weakify func with injected parameter
/// - Parameters:
/// - obj: weakified object
/// - method: method to call on weakified object
/// - value: injected value
/// - Returns: weakified function
public func weakify<Object: AnyObject, Input>(
_ obj: Object,
method: (
(Object) -> (Input) -> Void
)?,
inject value: Input
) -> (() -> Void) {
return { [weak obj] in
guard let obj = obj else { return }
method?(obj)(value)
}
}
/// Weakify func with injected parameter
/// - Parameters:
/// - obj: weakified object
/// - method: method to call on weakified object
/// - value: injected value
/// - Returns: weakified function
public func weakify<Object: AnyObject, Input1, Input2>(
_ obj: Object,
method: (
(Object) -> (Input1, Input2) -> Void
)?,
inject value1: Input1,
inject value2: Input2
) -> (() -> Void) {
return { [weak obj] in
guard let obj = obj else { return }
method?(obj)(value1, value2)
}
}
/// Weakify func with injected parameter
/// - Parameters:
/// - obj: weakified object
/// - method: method to call on weakified object
/// - Returns: weakified function
public func weakify<Object: AnyObject, Input>(
_ obj: Object,
method: (
(Object) -> () -> Void
)?
) -> ((Input) -> Void) {
return { [weak obj] _ in
guard let obj = obj else { return }
method?(obj)()
}
}
/// Function that helps convert function type to expected one, when expected parameter should be injected
/// - Parameters:
/// - value: injected value from "outside"
/// - method: given method which requires additional parameter
/// - Returns: void -> void closure which calls given method with injected parameter
public func injected<InjectedParameterType>(
value: InjectedParameterType,
into method: @escaping (
(InjectedParameterType) -> ()
)
) -> (() -> Void) {
{
method(value)
}
}
public func injected<InjectedParameterType1, InjectedParameterType2>(
value1: InjectedParameterType1,
value2: InjectedParameterType2,
into method: @escaping (
(InjectedParameterType1, InjectedParameterType2) -> ()
)
) -> (() -> Void) {
{
method(value1, value2)
}
}
public func injected<InjectedParameterType1, InjectedParameterType2, InjectedParameterType3>(
value1: InjectedParameterType1,
value2: InjectedParameterType2,
value3: InjectedParameterType3,
into method: @escaping (
(InjectedParameterType1, InjectedParameterType2, InjectedParameterType3) -> ()
)
) -> (() -> Void) {
{
method(value1, value2, value3)
}
}
/// Function that helps convert function type to expected one, when expected parameter may be omitted
/// - Parameter method: given void -> void closure
/// - Returns: same void -> void closure called within closure with parameter
public func erased<IgnoredParameterType>(
parameterFrom method: @escaping (
() -> ()
)
) -> ((IgnoredParameterType) -> Void) {
{ _ in
method()
}
}
/// Function that helps convert function type to expected one, when expected parameter may be omitted
/// - Parameter method: given void -> void closure
/// - Returns: same void -> void closure called within closure with parameter
public func erased<IgnoredParameterType>(
parameterFrom method: (
() -> Void
)?
) -> ((IgnoredParameterType) -> Void) {
{ _ in
method?()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment