package com.codepoetics.octarine.records;
import org.pcollections.HashTreePMap;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public interface Record {
static final Record EMPTY_RECORD = new HashRecord(HashTreePMap.empty());
@SafeVarargs
public static <S> Function<S, Record> reader(Function<S, Value>...readers) {
return s -> of(Stream.of(readers).map(r -> r.apply(s)));
}
public static Record empty() {
return EMPTY_RECORD;
}
public static Record of(Collection<Value> values) {
return of(values.stream());
}
public static Record of(Value...values) {
return values.length == 0 ? empty() : of(Stream.of(values));
}
public static Record of(Stream<Value> values) {
/*
* Collectors.toMap will call HashMap.merge() which will throw a NullPointerException if supplied with a null
* for the value parameter, so filter out null values first.
*/
return new HashRecord(HashTreePMap.from(values.filter(v -> null != v.value()).collect(Collectors.toMap(Value::key, Value::value))));
}
<T> Optional<T> get(Key<? extends T> key);
default <T> T getOrElse(Key<? extends T> key, T defaultValue) {
return get(key).orElse(defaultValue);
}
Set<Key<?>> keys();
Map<Key<?>, Object> values();
boolean containsKey(Key<?> key);
Record with(Value... values);
Record with(Record other);
default Record without(Key<?>... keys) {
return without(Stream.of(keys).collect(Collectors.toSet()));
}
Record without(Collection<Key<?>> keys);
MutableRecord mutable();
default Record immutable() {
return this;
}
Record select(Collection<Key<?>> selectedKeys);
default Record select(Key<?>... keys) {
return select(Stream.of(keys).collect(Collectors.toSet()));
}
}