001package Torello.JSON;
002
003import Torello.Java.Function.IntIntTConsumer;
004import Torello.Java.Additional.EffectivelyFinal;
005
006import java.util.function.Consumer;
007import java.util.function.Function;
008import java.util.function.Supplier;
009
010import java.util.stream.Stream;
011import java.util.stream.IntStream;
012import java.util.stream.LongStream;
013import java.util.stream.DoubleStream;
014
015
016public class SETTINGS_REC_BUILDER<T, U>
017{
018    // ********************************************************************************************
019    // ********************************************************************************************
020    // Parameters INTO a "SettingsRec" constructor, w/ getters
021    // ********************************************************************************************
022    // ********************************************************************************************
023
024
025    // The first four are set in the constructor: They are final and **CANNOT BE** initialized here
026    final T                     defaultValue;
027    final int                   FLAGS;
028    final Function<String, T>   userParser;
029    final BASIC_TYPES<T>        basicType;
030
031    // Set by the setters:  **MUST BE** initilized here, **OR ELSE**!
032    private Runnable                opener                      = () -> { };// UNUSED:  A NO-OP;
033    private Supplier<U>             closer                      = () -> null;
034    private Consumer<T>             oneArgAcceptor              = null;
035    private IntIntTConsumer<T>      threeArgAcceptor            = null;
036    private CHANGEABLE_CONSUMER<T>  changeableConsumer          = null;
037    private Boolean                 arrayGen1DRefOrPrimitive    = null;
038
039    // Package Private accessors
040    Runnable                opener()                    { return opener; }
041    Supplier<U>             closer()                    { return closer; }
042    Consumer<T>             oneArgAcceptor()            { return oneArgAcceptor; }
043    IntIntTConsumer<T>      threeArgAcceptor()          { return threeArgAcceptor; }
044    CHANGEABLE_CONSUMER<T>  changeableConsumer()        { return changeableConsumer; }
045    Boolean                 arrayGen1DRefOrPrimitive()  { return arrayGen1DRefOrPrimitive; }
046
047
048    // ********************************************************************************************
049    // ********************************************************************************************
050    // This Builder-Class Sole Constructor
051    // ********************************************************************************************
052    // ********************************************************************************************
053
054
055    SETTINGS_REC_BUILDER(
056            final T                     defaultValue,
057            final int                   FLAGS,
058            final Function<String, T>   userParser,
059            final BASIC_TYPES<T>        basicType
060        )
061    {
062        this.defaultValue   = defaultValue;
063        this.FLAGS          = FLAGS;
064        this.userParser     = userParser;
065        this.basicType      = basicType;
066    }
067
068
069    // ********************************************************************************************
070    // ********************************************************************************************
071    // Set-And-Build Methods
072    // ********************************************************************************************
073    // ********************************************************************************************
074
075
076    SettingsRec<T, Stream<T>> streams()
077    {
078        @SuppressWarnings("unchecked")
079        final SETTINGS_REC_BUILDER<T, Stream<T>> THIS = (SETTINGS_REC_BUILDER<T, Stream<T>>) this;
080        final EffectivelyFinal<Stream.Builder<T>> EF = new EffectivelyFinal<>(null);
081
082        THIS.oneArgAcceptor = (T t) -> EF.f.accept(t);          // Consumer<T> 
083        THIS.opener         = ()    -> EF.f = Stream.builder(); // Runnable
084        THIS.closer         = ()    -> EF.f.build();            // Supplier<Stream<T>>
085
086        return new SettingsRec<>(THIS);
087    }
088
089    SettingsRec<T, U> primitiveStreams(
090            final Consumer<T> oneArgAcceptor,
091            final Runnable    opener,
092            final Supplier<U> closer
093        )
094    {
095        this.oneArgAcceptor = oneArgAcceptor;
096        this.opener         = opener;
097        this.closer         = closer;
098
099        return new SettingsRec<>(this);
100    }
101
102
103    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
104    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
105    // Used For: JsonArray *INTO* a variety of Consumers<T>, IntIntTConsumers<T> and PrimConsumers
106    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
107    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
108
109
110    SettingsRec<T, Void> oneArgConsumer(final Consumer<T> userProvidedOneArgConsumer)
111    {
112        @SuppressWarnings("unchecked")
113        final SETTINGS_REC_BUILDER<T, Void> THIS = (SETTINGS_REC_BUILDER<T, Void>) this;
114        THIS.oneArgAcceptor = userProvidedOneArgConsumer;
115        return new SettingsRec<>(THIS);
116    }
117
118    SettingsRec<T, Void> threeArgConsumer(final IntIntTConsumer<T> userProvidedThreeArgConsumer)
119    {
120        @SuppressWarnings("unchecked")
121        final SETTINGS_REC_BUILDER<T, Void> THIS = (SETTINGS_REC_BUILDER<T, Void>) this;
122        THIS.threeArgAcceptor = userProvidedThreeArgConsumer;
123        return new SettingsRec<>(THIS);
124    }
125
126    // The actual user consumer is set into the SettingsRec *AFTER* the SettingsRec constructor
127    SettingsRec<T, Void> updateableConsumer(final boolean oneArgOrThreeArg)
128    {
129        @SuppressWarnings("unchecked")
130        final SETTINGS_REC_BUILDER<T, Void> THIS    = (SETTINGS_REC_BUILDER<T, Void>) this;
131        final CHANGEABLE_CONSUMER<T>        cc      = new CHANGEABLE_CONSUMER<>(oneArgOrThreeArg);
132        
133        THIS.changeableConsumer = cc;
134        this.opener             = cc::openerCode;
135
136        if (oneArgOrThreeArg)   THIS.oneArgAcceptor     = cc.wrappedUserConsumerV1;
137        else                    THIS.threeArgAcceptor   = cc.wrappedUserConsumerV2;
138
139        return new SettingsRec<>(THIS);
140    }
141
142
143    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
144    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
145    // Used For: JsonArray *INTO* Multi-Dimensinal Arrays
146    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
147    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
148
149
150    SettingsRec<T, Stream<T>> dimNArray()
151    {
152        @SuppressWarnings("unchecked")
153        final SETTINGS_REC_BUILDER<T, Stream<T>> THIS = 
154            (SETTINGS_REC_BUILDER<T, Stream<T>>) this;
155
156        final EffectivelyFinal<Stream.Builder<T>> EF = new EffectivelyFinal<>(null);
157
158        THIS.oneArgAcceptor = (T t) -> EF.f.accept(t);          // Consumer<T> 
159        THIS.opener         = ()    -> EF.f = Stream.builder(); // Runnable
160        THIS.closer         = ()    -> EF.f.build();            // Supplier<Stream<T>>;
161
162        THIS.arrayGen1DRefOrPrimitive = false;
163
164        return new SettingsRec<>(THIS);
165    }
166
167    SettingsRec<Integer, IntStream> dimNArrayIntPrim()
168    {
169        @SuppressWarnings("unchecked")
170        final SETTINGS_REC_BUILDER<Integer, IntStream> THIS = 
171            (SETTINGS_REC_BUILDER<Integer, IntStream>) this;
172
173        final EffectivelyFinal<IntStream.Builder> EF = new EffectivelyFinal<>(null);
174
175        THIS.oneArgAcceptor = (Integer i)   -> EF.f.accept(i);              // Consumer<Integer> 
176        THIS.opener         = ()            -> EF.f = IntStream.builder();  // Runnable
177        THIS.closer         = ()            -> EF.f.build();                // Supplier<IntStream>;
178
179        THIS.arrayGen1DRefOrPrimitive = false;
180
181        return new SettingsRec<>(THIS);
182    }
183
184    SettingsRec<Long, LongStream> dimNArrayLongPrim()
185    {
186        @SuppressWarnings("unchecked")
187        final SETTINGS_REC_BUILDER<Long, LongStream> THIS = 
188            (SETTINGS_REC_BUILDER<Long, LongStream>) this;
189
190        final EffectivelyFinal<LongStream.Builder> EF = new EffectivelyFinal<>(null);
191
192        THIS.oneArgAcceptor = (Long l)  -> EF.f.accept(l);              // Consumer<Long> 
193        THIS.opener         = ()        -> EF.f = LongStream.builder();  // Runnable
194        THIS.closer         = ()        -> EF.f.build();                // Supplier<LongStream>;
195
196        THIS.arrayGen1DRefOrPrimitive = false;
197
198        return new SettingsRec<>(THIS);
199    }
200
201    SettingsRec<Double, DoubleStream> dimNArrayDoublePrim()
202    {
203        @SuppressWarnings("unchecked")
204        final SETTINGS_REC_BUILDER<Double, DoubleStream> THIS = 
205            (SETTINGS_REC_BUILDER<Double, DoubleStream>) this;
206
207        final EffectivelyFinal<DoubleStream.Builder> EF = new EffectivelyFinal<>(null);
208
209        THIS.oneArgAcceptor = (Double d)    -> EF.f.accept(d);                  // Consumer<Double> 
210        THIS.opener         = ()            -> EF.f = DoubleStream.builder();   // Runnable
211        THIS.closer         = ()            -> EF.f.build();                    // Supplier<DoubleStream>;
212
213        this.arrayGen1DRefOrPrimitive = false;
214
215        return new SettingsRec<>(THIS);
216    }
217
218}