<commit_before>//
//  FallbackRenderer.swift
//  AsyncImageView
//
//  Created by <NAME> on 11/22/15.
//  Copyright © 2015 <NAME>. All rights reserved.
//

import UIKit
import ReactiveCocoa

/// `RendererType` decorator that will fall back from one `RendererType` to another.
public final class FallbackRenderer<T: RenderDataType, E1: ErrorType, E2: ErrorType>: RendererType {
	private let primaryRenderer: AnyRenderer<T, E1>
	private let fallbackRenderer: AnyRenderer<T, E2>

	public init<
		R1: RendererType, R2: RendererType
		where
		R1.RenderData == T,
		R2.RenderData == T,
		R1.Error == E1,
		R2.Error == E2
		>(primaryRenderer: R1, fallbackRenderer: R2) {
			self.primaryRenderer = AnyRenderer(renderer: primaryRenderer)
			self.fallbackRenderer = AnyRenderer(renderer: fallbackRenderer)
	}

	/// The resulting `SignalProducer` will emit images created by the primary
	/// renderer. If that emits an error, the fallback Renderer will be used.
	public func renderImageWithData(data: T) -> SignalProducer<UIImage, E2> {
		return self.primaryRenderer.renderImageWithData(data)
			.flatMapError { [fallback = self.fallbackRenderer] _ in
				return fallback.renderImageWithData(data)
			}
	}
}
<commit_msg>Introduced operator ??? to simplify FallbackRenderer. Fixes #7.<commit_after>//
//  FallbackRenderer.swift
//  AsyncImageView
//
//  Created by <NAME> on 11/22/15.
//  Copyright © 2015 <NAME>. All rights reserved.
//

import UIKit
import ReactiveCocoa

/// `RendererType` decorator that will fall back from one `RendererType` to another.
public final class FallbackRenderer<T: RenderDataType, E1: ErrorType, E2: ErrorType>: RendererType {
	private let primaryRenderer: AnyRenderer<T, E1>
	private let fallbackRenderer: AnyRenderer<T, E2>

	public init<
		R1: RendererType, R2: RendererType
		where
		R1.RenderData == T,
		R2.RenderData == T,
		R1.Error == E1,
		R2.Error == E2
		>(primaryRenderer: R1, fallbackRenderer: R2) {
			self.primaryRenderer = AnyRenderer(renderer: primaryRenderer)
			self.fallbackRenderer = AnyRenderer(renderer: fallbackRenderer)
	}

	/// The resulting `SignalProducer` will emit images created by the primary
	/// renderer. If that emits an error, the fallback Renderer will be used.
	public func renderImageWithData(data: T) -> SignalProducer<UIImage, E2> {
		return self.primaryRenderer.renderImageWithData(data)
			.flatMapError { [fallback = self.fallbackRenderer] _ in
				return fallback.renderImageWithData(data)
			}
	}
}

infix operator ??? { associativity left precedence 160 }

/// Allows creating FallbackRenderers with: `renderer1 ??? renderer2 ??? renderer3`.
public func ???<
	R1: RendererType, R2: RendererType
	where
	R1.RenderData == R2.RenderData
	>(primaryRenderer: R1, fallbackRenderer: R2) -> FallbackRenderer<R1.RenderData, R1.Error, R2.Error> {
	return FallbackRenderer(primaryRenderer: primaryRenderer, fallbackRenderer: fallbackRenderer)
}
{'fraction_non_alphanumeric': 0.10644161212538752, 'fraction_numerical': 0.022735101619014812, 'mean_word_length': 4.489603024574669, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3623364', 'n_tokens_mistral': 986, 'n_tokens_neox': 926, 'n_words': 262}