001/*
002 * Configurate
003 * Copyright (C) zml and Configurate contributors
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *    http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package ninja.leaping.configurate.reference;
018
019import ninja.leaping.configurate.ConfigurationNode;
020import ninja.leaping.configurate.reactive.Publisher;
021import org.checkerframework.checker.nullness.qual.Nullable;
022
023import java.util.function.Function;
024
025/**
026 * A pointer to a node within a configuration tree.
027 * <p>
028 * This value will update automatically with changes to the underlying configuration file. Subscribers will be provided
029 * the current value upon subscription, followed by any changes.
030 *
031 * @param <T> The type of value to return
032 */
033public interface ValueReference<T> extends Publisher<T> {
034    /**
035     * Get the current value at this node
036     * <p>
037     * Any deserialization failures will be submitted to the owning {@link ConfigurationReference}'s error callback
038     *
039     * @return the deserialized value, or null if deserialization fails.
040     */
041    @Nullable T get();
042
043    /**
044     * Set the new value of this node. The configuration won't be saved.
045     * <p>
046     * Any serialization errors will be provided to the error callback of the owning {@link ConfigurationReference}
047     *
048     * @param value The value
049     * @return true if successful, false if serialization fails
050     */
051    boolean set(@Nullable T value);
052
053    /**
054     * Set the new value of this node and save the underlying configuration
055     * <p>
056     * Any serialization errors will be provided to the error callback of the owning {@link ConfigurationReference}
057     *
058     * @param value The value
059     * @return true if successful, false if serialization fails
060     */
061    boolean setAndSave(@Nullable T value);
062
063    /**
064     * Set the new value of this node and save the underlying configuration asynchronously on the executor of the owning
065     * {@link ConfigurationReference}
066     * <p>
067     * Any serialization errors will be submitted to subscribers of the returned {@link Publisher}
068     *
069     * @param value The value
070     * @return true if successful, false if serialization fails
071     */
072    Publisher<Boolean> setAndSaveAsync(@Nullable T value);
073
074    /**
075     * Update this value and the underlying node, without saving.
076     * <p>
077     * Any serialization errors will be provided to the error callback of the owning {@link ConfigurationReference}
078     *
079     * @param action to transform this node's value
080     * @return whether this update was successful
081     */
082    boolean update(Function<@Nullable T, ? extends T> action);
083
084    /**
085     * Update, performing the action and save on the executor of the owning {@link ConfigurationReference}. Any errors
086     * that occur while saving will be passed along to any subscribers.
087     * <p>
088     * The updated value will only be exposed if the changes are successful.
089     *
090     * @param action to transform this node's value
091     * @return whether this update was successful
092     */
093    Publisher<Boolean> updateAsync(Function<T, ? extends T> action);
094
095    /**
096     * Get the node this value reference points to.
097     *
098     * @return The node
099     */
100    ConfigurationNode getNode();
101}