001package org.nasdanika.rag.core;
002
003import java.util.function.BiFunction;
004import java.util.function.Function;
005
006import org.nasdanika.common.ProgressMonitor;
007
008/**
009 * Extracts key (e.g. a vector) from value (e.g. String)
010 * @param <V> value type
011 * @param <K> key type
012 */
013public interface KeyExtractor<V,K> {
014        
015        K extract(V value, ProgressMonitor progressMonitor);
016        
017        static <V,K> KeyExtractor<V,K> from(Function<V,K> function) {
018                return (value, progressMonitor) -> function.apply(value);
019        }
020        
021        static <V,K> KeyExtractor<V,K> from(BiFunction<V, ProgressMonitor, K> biFunction) {
022                return biFunction::apply;
023        }
024        
025        default <L> KeyExtractor<V,L> then(Function<K,L> after) {
026                return (value, progressMonitor) -> after.apply(extract(value, progressMonitor));
027        }
028        
029        default <L> KeyExtractor<V,L> then(BiFunction<K, ProgressMonitor, L> after) {
030                return (value, progressMonitor) -> after.apply(extract(value, progressMonitor), progressMonitor);
031        }
032        
033        default <U> KeyExtractor<U,K> before(Function<U,V> before) {
034                return (value, progressMonitor) -> extract(before.apply(value), progressMonitor);
035        }
036        
037        default <U> KeyExtractor<U,K> before(BiFunction<U, ProgressMonitor, V> before) {
038                return (value, progressMonitor) -> extract(before.apply(value, progressMonitor), progressMonitor);
039        }
040        
041        @SuppressWarnings("unchecked")
042        default <T extends KeyExtractor<?,?>> T adapt(Class<T> type) {
043                if (type.isInstance(this)) {
044                        return (T) this;
045                }
046                
047                throw new UnsupportedOperationException("Cannot adapt " + this + " to " + type);
048        }
049
050}