added iOS source code
[wl-app.git] / iOS / Pods / Kingfisher / Sources / KingfisherOptionsInfo.swift
diff --git a/iOS/Pods/Kingfisher/Sources/KingfisherOptionsInfo.swift b/iOS/Pods/Kingfisher/Sources/KingfisherOptionsInfo.swift
new file mode 100755 (executable)
index 0000000..ebe4b31
--- /dev/null
@@ -0,0 +1,355 @@
+//
+//  KingfisherOptionsInfo.swift
+//  Kingfisher
+//
+//  Created by Wei Wang on 15/4/23.
+//
+//  Copyright (c) 2018 Wei Wang <onevcat@gmail.com>
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+
+#if os(macOS)
+import AppKit
+#else
+import UIKit
+#endif
+    
+
+/**
+*      KingfisherOptionsInfo is a typealias for [KingfisherOptionsInfoItem]. You can use the enum of option item with value to control some behaviors of Kingfisher.
+*/
+public typealias KingfisherOptionsInfo = [KingfisherOptionsInfoItem]
+let KingfisherEmptyOptionsInfo = [KingfisherOptionsInfoItem]()
+
+/**
+Items could be added into KingfisherOptionsInfo.
+*/
+public enum KingfisherOptionsInfoItem {
+    /// The associated value of this member should be an ImageCache object. Kingfisher will use the specified
+    /// cache object when handling related operations, including trying to retrieve the cached images and store
+    /// the downloaded image to it.
+    case targetCache(ImageCache)
+    
+    /// Cache for storing and retrieving original image.
+    /// Preferred prior to targetCache for storing and retrieving original images if specified.
+    /// Only used if a non-default image processor is involved.
+    case originalCache(ImageCache)
+    
+    /// The associated value of this member should be an ImageDownloader object. Kingfisher will use this
+    /// downloader to download the images.
+    case downloader(ImageDownloader)
+    
+    /// Member for animation transition when using UIImageView. Kingfisher will use the `ImageTransition` of
+    /// this enum to animate the image in if it is downloaded from web. The transition will not happen when the
+    /// image is retrieved from either memory or disk cache by default. If you need to do the transition even when
+    /// the image being retrieved from cache, set `ForceTransition` as well.
+    case transition(ImageTransition)
+    
+    /// Associated `Float` value will be set as the priority of image download task. The value for it should be
+    /// between 0.0~1.0. If this option not set, the default value (`NSURLSessionTaskPriorityDefault`) will be used.
+    case downloadPriority(Float)
+    
+    /// If set, `Kingfisher` will ignore the cache and try to fire a download task for the resource.
+    case forceRefresh
+
+    /// If set, `Kingfisher` will try to retrieve the image from memory cache first. If the image is not in memory
+    /// cache, then it will ignore the disk cache but download the image again from network. This is useful when
+    /// you want to display a changeable image behind the same url, while avoiding download it again and again.
+    case fromMemoryCacheOrRefresh
+    
+    /// If set, setting the image to an image view will happen with transition even when retrieved from cache.
+    /// See `Transition` option for more.
+    case forceTransition
+    
+    ///  If set, `Kingfisher` will only cache the value in memory but not in disk.
+    case cacheMemoryOnly
+    
+    /// If set, `Kingfisher` will only try to retrieve the image from cache not from network.
+    case onlyFromCache
+    
+    /// Decode the image in background thread before using.
+    case backgroundDecode
+    
+    /// The associated value of this member will be used as the target queue of dispatch callbacks when
+    /// retrieving images from cache. If not set, `Kingfisher` will use main quese for callbacks.
+    case callbackDispatchQueue(DispatchQueue?)
+    
+    /// The associated value of this member will be used as the scale factor when converting retrieved data to an image.
+    /// It is the image scale, instead of your screen scale. You may need to specify the correct scale when you dealing 
+    /// with 2x or 3x retina images.
+    case scaleFactor(CGFloat)
+
+    /// Whether all the animated image data should be preloaded. Default it false, which means following frames will be
+    /// loaded on need. If true, all the animated image data will be loaded and decoded into memory. This option is mainly
+    /// used for back compatibility internally. You should not set it directly. `AnimatedImageView` will not preload
+    /// all data, while a normal image view (`UIImageView` or `NSImageView`) will load all data. Choose to use
+    /// corresponding image view type instead of setting this option.
+    case preloadAllAnimationData
+    
+    /// The `ImageDownloadRequestModifier` contained will be used to change the request before it being sent.
+    /// This is the last chance you can modify the request. You can modify the request for some customizing purpose,
+    /// such as adding auth token to the header, do basic HTTP auth or something like url mapping. The original request
+    /// will be sent without any modification by default.
+    case requestModifier(ImageDownloadRequestModifier)
+    
+    /// Processor for processing when the downloading finishes, a processor will convert the downloaded data to an image
+    /// and/or apply some filter on it. If a cache is connected to the downloader (it happens when you are using
+    /// KingfisherManager or the image extension methods), the converted image will also be sent to cache as well as the
+    /// image view. `DefaultImageProcessor.default` will be used by default.
+    case processor(ImageProcessor)
+    
+    /// Supply an `CacheSerializer` to convert some data to an image object for
+    /// retrieving from disk cache or vice versa for storing to disk cache.
+    /// `DefaultCacheSerializer.default` will be used by default.
+    case cacheSerializer(CacheSerializer)
+
+    /// Modifier for modifying an image right before it is used.
+    /// If the image was fetched directly from the downloader, the modifier will
+    /// run directly after the processor.
+    /// If the image is being fetched from a cache, the modifier will run after
+    /// the cacheSerializer.
+    /// Use `ImageModifier` when you need to set properties on a concrete type
+    /// of `Image`, such as a `UIImage`, that do not persist when caching the image.
+    case imageModifier(ImageModifier)
+    
+    /// Keep the existing image while setting another image to an image view.
+    /// By setting this option, the placeholder image parameter of imageview extension method
+    /// will be ignored and the current image will be kept while loading or downloading the new image.
+    case keepCurrentImageWhileLoading
+    
+    /// If set, Kingfisher will only load the first frame from a animated image data file as a single image.
+    /// Loading a lot of animated images may take too much memory. It will be useful when you want to display a
+    /// static preview of the first frame from a animated image.
+    /// This option will be ignored if the target image is not animated image data.
+    case onlyLoadFirstFrame
+    
+    /// If set and an `ImageProcessor` is used, Kingfisher will try to cache both 
+    /// the final result and original image. Kingfisher will have a chance to use 
+    /// the original image when another processor is applied to the same resouce, 
+    /// instead of downloading it again.
+    case cacheOriginalImage
+}
+
+precedencegroup ItemComparisonPrecedence {
+    associativity: none
+    higherThan: LogicalConjunctionPrecedence
+}
+
+infix operator <== : ItemComparisonPrecedence
+
+// This operator returns true if two `KingfisherOptionsInfoItem` enum is the same, without considering the associated values.
+func <== (lhs: KingfisherOptionsInfoItem, rhs: KingfisherOptionsInfoItem) -> Bool {
+    switch (lhs, rhs) {
+    case (.targetCache(_), .targetCache(_)): return true
+    case (.originalCache(_), .originalCache(_)): return true
+    case (.downloader(_), .downloader(_)): return true
+    case (.transition(_), .transition(_)): return true
+    case (.downloadPriority(_), .downloadPriority(_)): return true
+    case (.forceRefresh, .forceRefresh): return true
+    case (.fromMemoryCacheOrRefresh, .fromMemoryCacheOrRefresh): return true
+    case (.forceTransition, .forceTransition): return true
+    case (.cacheMemoryOnly, .cacheMemoryOnly): return true
+    case (.onlyFromCache, .onlyFromCache): return true
+    case (.backgroundDecode, .backgroundDecode): return true
+    case (.callbackDispatchQueue(_), .callbackDispatchQueue(_)): return true
+    case (.scaleFactor(_), .scaleFactor(_)): return true
+    case (.preloadAllAnimationData, .preloadAllAnimationData): return true
+    case (.requestModifier(_), .requestModifier(_)): return true
+    case (.processor(_), .processor(_)): return true
+    case (.cacheSerializer(_), .cacheSerializer(_)): return true
+    case (.imageModifier(_), .imageModifier(_)): return true
+    case (.keepCurrentImageWhileLoading, .keepCurrentImageWhileLoading): return true
+    case (.onlyLoadFirstFrame, .onlyLoadFirstFrame): return true
+    case (.cacheOriginalImage, .cacheOriginalImage): return true
+    default: return false
+    }
+}
+
+
+extension Collection where Iterator.Element == KingfisherOptionsInfoItem {
+    func lastMatchIgnoringAssociatedValue(_ target: Iterator.Element) -> Iterator.Element? {
+        return reversed().first { $0 <== target }
+    }
+    
+    func removeAllMatchesIgnoringAssociatedValue(_ target: Iterator.Element) -> [Iterator.Element] {
+        return filter { !($0 <== target) }
+    }
+}
+
+public extension Collection where Iterator.Element == KingfisherOptionsInfoItem {
+    /// The target `ImageCache` which is used.
+    public var targetCache: ImageCache {
+        if let item = lastMatchIgnoringAssociatedValue(.targetCache(.default)),
+            case .targetCache(let cache) = item
+        {
+            return cache
+        }
+        return ImageCache.default
+    }
+    
+    /// The original `ImageCache` which is used.
+    public var originalCache: ImageCache {
+        if let item = lastMatchIgnoringAssociatedValue(.originalCache(.default)),
+            case .originalCache(let cache) = item
+        {
+            return cache
+        }
+        return targetCache
+    }
+    
+    /// The `ImageDownloader` which is specified.
+    public var downloader: ImageDownloader {
+        if let item = lastMatchIgnoringAssociatedValue(.downloader(.default)),
+            case .downloader(let downloader) = item
+        {
+            return downloader
+        }
+        return ImageDownloader.default
+    }
+    
+    /// Member for animation transition when using UIImageView.
+    public var transition: ImageTransition {
+        if let item = lastMatchIgnoringAssociatedValue(.transition(.none)),
+            case .transition(let transition) = item
+        {
+            return transition
+        }
+        return ImageTransition.none
+    }
+    
+    /// A `Float` value set as the priority of image download task. The value for it should be
+    /// between 0.0~1.0.
+    public var downloadPriority: Float {
+        if let item = lastMatchIgnoringAssociatedValue(.downloadPriority(0)),
+            case .downloadPriority(let priority) = item
+        {
+            return priority
+        }
+        return URLSessionTask.defaultPriority
+    }
+    
+    /// Whether an image will be always downloaded again or not.
+    public var forceRefresh: Bool {
+        return contains{ $0 <== .forceRefresh }
+    }
+
+    /// Whether an image should be got only from memory cache or download.
+    public var fromMemoryCacheOrRefresh: Bool {
+        return contains{ $0 <== .fromMemoryCacheOrRefresh }
+    }
+    
+    /// Whether the transition should always happen or not.
+    public var forceTransition: Bool {
+        return contains{ $0 <== .forceTransition }
+    }
+    
+    /// Whether cache the image only in memory or not.
+    public var cacheMemoryOnly: Bool {
+        return contains{ $0 <== .cacheMemoryOnly }
+    }
+    
+    /// Whether only load the images from cache or not.
+    public var onlyFromCache: Bool {
+        return contains{ $0 <== .onlyFromCache }
+    }
+    
+    /// Whether the image should be decoded in background or not.
+    public var backgroundDecode: Bool {
+        return contains{ $0 <== .backgroundDecode }
+    }
+
+    /// Whether the image data should be all loaded at once if it is an animated image.
+    public var preloadAllAnimationData: Bool {
+        return contains { $0 <== .preloadAllAnimationData }
+    }
+    
+    /// The queue of callbacks should happen from Kingfisher.
+    public var callbackDispatchQueue: DispatchQueue {
+        if let item = lastMatchIgnoringAssociatedValue(.callbackDispatchQueue(nil)),
+            case .callbackDispatchQueue(let queue) = item
+        {
+            return queue ?? DispatchQueue.main
+        }
+        return DispatchQueue.main
+    }
+    
+    /// The scale factor which should be used for the image.
+    public var scaleFactor: CGFloat {
+        if let item = lastMatchIgnoringAssociatedValue(.scaleFactor(0)),
+            case .scaleFactor(let scale) = item
+        {
+            return scale
+        }
+        return 1.0
+    }
+    
+    /// The `ImageDownloadRequestModifier` will be used before sending a download request.
+    public var modifier: ImageDownloadRequestModifier {
+        if let item = lastMatchIgnoringAssociatedValue(.requestModifier(NoModifier.default)),
+            case .requestModifier(let modifier) = item
+        {
+            return modifier
+        }
+        return NoModifier.default
+    }
+    
+    /// `ImageProcessor` for processing when the downloading finishes.
+    public var processor: ImageProcessor {
+        if let item = lastMatchIgnoringAssociatedValue(.processor(DefaultImageProcessor.default)),
+            case .processor(let processor) = item
+        {
+            return processor
+        }
+        return DefaultImageProcessor.default
+    }
+
+    /// `ImageModifier` for modifying right before the image is displayed.
+    public var imageModifier: ImageModifier {
+        if let item = lastMatchIgnoringAssociatedValue(.imageModifier(DefaultImageModifier.default)),
+            case .imageModifier(let imageModifier) = item
+        {
+            return imageModifier
+        }
+        return DefaultImageModifier.default
+    }
+    
+    /// `CacheSerializer` to convert image to data for storing in cache.
+    public var cacheSerializer: CacheSerializer {
+        if let item = lastMatchIgnoringAssociatedValue(.cacheSerializer(DefaultCacheSerializer.default)),
+            case .cacheSerializer(let cacheSerializer) = item
+        {
+            return cacheSerializer
+        }
+        return DefaultCacheSerializer.default
+    }
+    
+    /// Keep the existing image while setting another image to an image view. 
+    /// Or the placeholder will be used while downloading.
+    public var keepCurrentImageWhileLoading: Bool {
+        return contains { $0 <== .keepCurrentImageWhileLoading }
+    }
+    
+    public var onlyLoadFirstFrame: Bool {
+        return contains { $0 <== .onlyLoadFirstFrame }
+    }
+    
+    public var cacheOriginalImage: Bool {
+        return contains { $0 <== .cacheOriginalImage }
+    }
+}