}s. This can be handy if
* you have an Output<SomeType>
and you want to get a transitive dependency of it. i.e.:
*
*
* Output<SomeType> d1 = ...;
* Output<OtherType> {@literal d2 = d1.apply(v -> v.otherOutput);} // getting an output off of 'v'.
*
*
* In this example, taking a dependency on d2 means a resource will depend on all the resources
* of d1. It will not depend on the resources of v.x.y.OtherDep.
*
* Importantly, the Resources that d2 feels like it will depend on are the same resources
* as d1.
*
* If you need have multiple {@link Output}{@literal }s and a single {@link Output}{@literal }
* is needed that combines both set of resources, then {@link Output#all(Output[])}
* or {@link Output#tuple(Output, Output, Output)} should be used instead.
*
* This function will only be called during execution of a pulumi up
request.
* It will not run during pulumi preview
* (as the values of resources are of course not known then).
*
* @param type of the {@link Output} returned by {@code func}
* @param func the function to apply to the current value
* @return an {@link Output} after applying {@code func}
*/
Output apply(Function> func);
/**
* @param type returned by {@code func}
* @param func the function to apply to the current value
* @return an {@link Output} after applying {@code func}
* @see Output#apply(Function) for more details.
*/
default Output applyValue(Function func) {
return apply(t -> Output.ofNullable(func.apply(t)));
}
/**
* Creates a shallow copy (the underlying CompletableFuture is copied) of this {@link Output}{@literal }
*
* @return a shallow copy of the {@link Output}{@literal }
*/
Output copy();
/**
* Returns a new {@link Output}{@literal } which is a copy of the existing output but marked as
* a non-secret. The original output or input is not modified in any way.
* Please use with caution
*
* @return this {@link Output} as a non-secret
*/
Output asPlaintext();
/**
* Returns a new {@link Output}{@literal } which is a copy of the existing output but marked as
* a secret. The original output or input is not modified in any way.
*
* @return this {@link Output} as a secret
*/
Output asSecret();
// Static section -----
/**
* Returns an {@code Output}{@literal } describing the given non-{@code null} value.
*
* @param value the value to describe, which must be non-{@code null}
* @param the type of the value
* @return an {@code Output}{@literal } with the value present
* @throws NullPointerException if value is {@code null}
*/
static Output of(T value) {
requireNonNull(value);
return new OutputInternal<>(value);
}
/**
* Returns an {@code Output}{@literal } describing a future value.
*
* @param future the future to describe, which must be non-{@code null}
* @param the type of the value
* @return an {@code Output}{@literal } with the value present
* @throws NullPointerException if future is {@code null}, but not the future value
*/
static Output of(CompletableFuture future) {
return new OutputInternal<>(future, false);
}
/**
* Returns an {@code Output}{@literal } describing the given non-{@code null} secret value.
*
* @param value the secret value to describe, which must be non-{@code null}
* @param the type of the value
* @return an {@code Output}{@literal } with the value present
* @throws NullPointerException if value is {@code null}
*/
static Output ofSecret(T value) {
return new OutputInternal<>(value, true);
}
/**
* Returns an {@code Output}{@literal } describing the given value, if
* non-{@code null}, otherwise returns an empty {@code Output}{@literal }.
*
* @param value the possibly-{@code null} value to describe
* @param the type of the value
* @return an {@code Output}{@literal } with a present value if the specified value
* is non-{@code null}, otherwise an empty {@code Output}{@literal }
*/
static Output ofNullable(@Nullable T value) {
return new OutputInternal<>(value);
}
/**
* Combines all the {@link Output}{@literal } values in {@code outputs}
* into a single {@link Output}{@literal } with an {@link java.util.List}{@literal }
* containing all their underlying values.
*
* If any of the {@link Output}{@literal }s are not known, the final result will be not known.
* Similarly, if any of the {@link Output}{@literal }s are secrets, then the final result will be a secret.
*
* @param the type of the value
* @param outputs the outputs to be combined
* @return an {@link Output} with a list of all values of the given {@code outputs}
*/
@SafeVarargs // safe because we only call List.of, that is also @SafeVarargs
static Output> all(Output... outputs) {
return all(Stream.of(outputs));
}
/**
* @param the type of the value
* @param outputs the outputs to be combined
* @return an {@link Output} with a list of all values of the given {@code outputs}
* @see Output#all(Output[]) for more details.
*/
static Output> all(Iterable> outputs) {
return all(StreamSupport.stream(outputs.spliterator(), /* not parallel */ false));
}
private static Output> all(Stream> outputs) {
var data = outputs
.map(output -> Internal.of(output).getDataAsync())
.collect(toCollection(ArrayList::new)); // ArrayList preserves null
var futureResult = CompletableFutures.flatAllOf(data)
.thenApply(completed -> completed.stream().map(Output::joinOrThrow)) // already complete at this point
.thenApply(Output::accumulateOutputData);
return new OutputInternal<>(futureResult);
}
/**
* Takes in a {@code formattableString} with potential {@link Output} or a regular {@link Object}.
* in the 'placeholder holes'.
* Conceptually, this method unwraps all the underlying values in the holes,
* combines them appropriately with the {@code formattableString}, and produces an {@link Output}
* containing the final result.
*
* If any of the {@link Output}s are not known, the
* final result will be not known.
*
* Similarly, if any of the {@link Output}s are secrets,
* then the final result will be a secret.
*
* @param formattableString The format string with same syntax as expected by {@link String#format(String, Object...)},
* the behaviour on a {@code null} argument depends on the format conversion.
* @param arguments {@link Output}s or regular {@link Object}s that values of will be applied to the format String
* @return an {@link Output} with the result of the formatting
*/
static Output format(String formattableString, @Nullable Object... arguments) {
var argumentsOrEmpty = arguments == null ? List.of() : newArrayList(arguments);
var outputs = argumentsOrEmpty.stream().map(Output::ensureOutput);
return Output.all(outputs).applyValue(objs -> String.format(formattableString, objs.toArray()));
}
private static Output ensureOutput(@Nullable Object o) {
if (o instanceof Output) {
//noinspection unchecked
return (Output) o;
}
return Output.ofNullable(o);
}
private static OutputData joinOrThrow(CompletableFuture> futureData) {
var d = futureData.join();
return requireNonNull(d, "unexpected null OutputData from a CompletableFuture");
}
private static OutputData> accumulateOutputData(Stream> nullableStream) {
return OutputData.builder(new ArrayList()) // ArrayList preserves null
.accumulate(nullableStream, (ts, t) -> {
ts.add(t);
return ts;
})
.build(ts -> ts);
}
// Convenience methods for Either (a.k.a. Union)
/**
* Represents an {@link Output} value that can be one of two different types.
* For example, it might potentially be an "Integer" some time
* or a "String" in other cases.
*
* @param the type contained by the {@link Left} instance
* @param the type contained by the {@link Right} instance
* @param value the value to create the {@link Left} instance with
* @return an {@link Output} holding {@link Left} instance with the given value
*/
static Output> ofLeft(L value) {
return Output.of(Either.ofLeft(value));
}
/**
* @param the type contained by the {@link Left} instance
* @param the type contained by the {@link Right} instance
* @param value the value to create the {@link Right} instance with
* @return an {@link Output} holding {@link Right} instance with the given value
* @see #ofLeft(Object)
*/
static Output> ofRight(R value) {
return Output.of(Either.ofRight(value));
}
/**
* @param the type contained by the {@link Left} instance
* @param the type contained by the {@link Right} instance
* @param value an {@link Output} with the value to create the {@link Left} instance with
* @return an {@link Output} holding {@link Left} instance with the value of the given {@link Output}
* @see #ofLeft(Object)
*/
static Output> ofLeft(Output value) {
return new OutputInternal<>(Internal.of(value).getDataAsync()
.thenApply(ioData -> ioData.apply(Either::ofLeft)));
}
/**
* @param the type contained by the {@link Left} instance
* @param the type contained by the {@link Right} instance
* @param value an {@link Output} with the value to create the {@link Right} instance with
* @return an {@link Output} holding {@link Right} instance with the value of the given {@link Output}
* @see #ofLeft(Object)
*/
static Output> ofRight(Output value) {
return new OutputInternal<>(Internal.of(value).getDataAsync()
.thenApply(ioData -> ioData.apply(Either::ofRight)));
}
// Convenience methods for JSON
/**
* @return a {@link JsonNull#INSTANCE}
* @see #ofJson(JsonElement)
*/
static Output ofJson() {
return ofJson(JsonNull.INSTANCE);
}
/**
* Represents an {@link Output} value that wraps a {@link JsonElement}
*
* @param json the {@link JsonElement} to wrap
* @return given {@link JsonElement} wrapped in an {@link Output}
*/
static Output ofJson(JsonElement json) {
return Output.of(json);
}
/**
* @param json the json value to wrap
* @return given json value as a {@link JsonElement} wrapped in an {@link Output}
* @throws com.google.gson.JsonSyntaxException – if json is not valid
* @see #ofJson(JsonElement)
*/
static Output parseJson(String json) {
var gson = new Gson();
return ofJson(gson.fromJson(json, JsonElement.class));
}
/**
* @param json the json value wrapped in an {@link Output}{@literal }
* @return given json value as a {@link JsonElement} wrapped in an {@link Output}
* @throws com.google.gson.JsonSyntaxException – if json is not valid
* @see #ofJson(JsonElement)
*/
static Output parseJson(Output json) {
var gson = new Gson();
return json.applyValue((String j) -> gson.fromJson(j, JsonElement.class));
}
// Convenience methods for List
/**
* Returns a shallow copy of the {@link List} wrapped in an {@link Output}
*
* @return an {@link Output} holding a copy of the given list
*/
static Output> copyOfList(List values) {
return Output.of(ImmutableList.copyOf(values));
}
/**
* Concatenates two lists of {@link Output}, can take a {@code null} value that will be treated as an empty list,
* always returns {@code non-null}.
*
* @param type of the list element
* @param left fist list to concatenate
* @param right second list to concatenate
* @return an {@link Output} with {@code left} and {@code right} lists concatenated
*/
@Nonnull
static Output> concatList(@Nullable Output* @Nullable */ List> left, @Nullable Output* @Nullable */List> right) {
return tuple(
left == null ? Output.of(List.of()) : left,
right == null ? Output.of(List.of()) : right
).applyValue(tuple -> ImmutableList.builder()
.addAll(tuple.t1 == null ? List.of() : tuple.t1)
.addAll(tuple.t2 == null ? List.of() : tuple.t2)
.build());
}
/**
* @return an {@link Output} with an empty {@link List}
* @see #ofList(Object)
* @see #listBuilder()
*/
static Output> ofList() {
return Output.of(ImmutableList.of());
}
/**
* @return an {@link Output} value that wraps a {@link List} with one element.
* @see #ofList(Object)
* @see #listBuilder()
*/
static Output> ofList(E e1) {
return Output.of(ImmutableList.of(e1));
}
/**
* @return an {@link Output} value that wraps a {@link List} with two elements.
* @see #ofList(Object)
* @see #listBuilder()
*/
static Output> ofList(E e1, E e2) {
return Output.of(ImmutableList.of(e1, e2));
}
/**
* @return an {@link Output} value that wraps a {@link List} with three elements.
* @see #ofList(Object)
* @see #listBuilder()
*/
static Output> ofList(E e1, E e2, E e3) {
return Output.of(ImmutableList.of(e1, e2, e3));
}
/**
* @return an {@link Output} value that wraps a {@link List} with four elements.
* @see #ofList(Object)
* @see #listBuilder()
*/
static Output> ofList(E e1, E e2, E e3, E e4) {
return Output.of(ImmutableList.of(e1, e2, e3, e4));
}
/**
* @return an {@link Output} value that wraps a {@link List} with five elements.
* @see #ofList(Object)
* @see #listBuilder()
*/
static Output> ofList(E e1, E e2, E e3, E e4, E e5) {
return Output.of(ImmutableList.of(e1, e2, e3, e4, e5));
}
/**
* @return an {@link Output} value that wraps a {@link List} with six elements.
* @see #ofList(Object)
* @see #listBuilder()
*/
static Output> ofList(E e1, E e2, E e3, E e4, E e5, E e6) {
return Output.of(ImmutableList.of(e1, e2, e3, e4, e5, e6));
}
/**
* @return an {@link Output} value that wraps a {@link List} with seven elements.
* @see #ofList(Object)
* @see #listBuilder()
*/
static Output> ofList(E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
return Output.of(ImmutableList.of(e1, e2, e3, e4, e5, e6, e7));
}
/**
* @return an {@link Output} value that wraps a {@link List} with eight elements.
* @see #ofList(Object)
* @see #listBuilder()
*/
static Output> ofList(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
return Output.of(ImmutableList.of(e1, e2, e3, e4, e5, e6, e7, e8));
}
/**
* @return an {@link Output} value that wraps a {@link List} with nine elements.
* @see #ofList(Object)
* @see #listBuilder()
*/
static Output> ofList(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
return Output.of(ImmutableList.of(e1, e2, e3, e4, e5, e6, e7, e8, e9));
}
/**
* @return an {@link Output} value that wraps a {@link List} with ten elements.
* @see #ofList(Object)
* @see #listBuilder()
*/
static Output> ofList(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
return Output.of(ImmutableList.of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10));
}
/**
* @return an {@link Output} value that wraps a {@link List} with eleven elements.
* @see #ofList(Object)
* @see #listBuilder()
*/
static Output> ofList(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11) {
return Output.of(ImmutableList.of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11));
}
/**
* @return an {@link Output} value that wraps a {@link List} with twelve elements.
* @see #ofList(Object)
* @see #listBuilder()
*/
static Output> ofList(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11, E e12) {
return Output.of(ImmutableList.of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12));
}
/**
* @return an {@link Output} value that wraps a {@link List} with more than twelve elements.
* @see #ofList(Object)
* @see #listBuilder()
*/
@SafeVarargs
static Output> ofList(
E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11, E e12, E... others) {
return Output.of(ImmutableList.of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, others));
}
/**
* Helps to build an {@link Output} that wraps a {@link List}.
*
* @return an {@link Output.ListBuilder}{@literal } instance
* @see #ofList(Object)
*/
static Output.ListBuilder listBuilder() {
return new Output.ListBuilder<>();
}
/**
* A {@link List} wrapped in an {@link Output} builder.
*/
final class ListBuilder {
private final CompletableFutures.Builder>> builder;
public ListBuilder() {
builder = CompletableFutures.builder(
CompletableFuture.completedFuture(OutputData.builder(ImmutableList.builder()))
);
}
@CanIgnoreReturnValue
public Output.ListBuilder add(Output value) {
this.builder.accumulate(
Internal.of(value).getDataAsync(),
(dataBuilder, data) -> dataBuilder.accumulate(data, ImmutableList.Builder::add)
);
return this;
}
@CanIgnoreReturnValue
public Output.ListBuilder add(E value) {
this.builder.accumulate(
CompletableFuture.completedFuture(OutputData.of(value)),
(dataBuilder, data) -> dataBuilder.accumulate(data, ImmutableList.Builder::add)
);
return this;
}
@SafeVarargs
@CanIgnoreReturnValue
public final Output.ListBuilder add(E... elements) {
return addAll(List.of(elements));
}
@CanIgnoreReturnValue
public Output.ListBuilder addAll(Iterable extends E> elements) {
this.builder.accumulate(
CompletableFuture.completedFuture(OutputData.of(elements)),
(dataBuilder, data) -> dataBuilder.accumulate(data, ImmutableList.Builder::addAll)
);
return this;
}
@CanIgnoreReturnValue
public Output.ListBuilder addAll(Iterator extends E> elements) {
this.builder.accumulate(
CompletableFuture.completedFuture(OutputData.of(elements)),
(dataBuilder, data) -> dataBuilder.accumulate(data, ImmutableList.Builder::addAll)
);
return this;
}
public Output> build() {
return new OutputInternal<>(builder.build(dataBuilder -> dataBuilder.build(ImmutableList.Builder::build)));
}
}
// Convenience methods for Map
/**
* Returns a shallow copy of the {@link Map} wrapped in an {@link Output}
*
* @return an {@link Output} holding a copy of the given map
*/
static Output> copyOfMap(Map values) {
return Output.of(ImmutableMap.copyOf(values));
}
/**
* Concatenates two {@link Map} wrapped in an {@link Output}.
* Returns a new instance without modifying any of the arguments.
*
* If both maps contain the same key, the value from the second map takes over.
*
* {@code null} values in the Output or Map layer are treated as empty maps.
*
* @param type of the map value
* @param left The first @see {@code Output>} to concatenate
* @param right The second @see {@code Output>} to concatenate, it has higher priority in case of key clash
* @return an {@code Output>} that contains the items from both maps given
*/
static Output> concatMap(@Nullable Output> left, @Nullable Output> right) {
return tuple(
left == null ? Output.of(Map.of()) : left,
right == null ? Output.of(Map.of()) : right
).applyValue(tuple ->
Stream.concat(
(tuple.t1 == null ? ImmutableMap.of() : tuple.t1).entrySet().stream(),
(tuple.t2 == null ? ImmutableMap.of() : tuple.t2).entrySet().stream()
).collect(toImmutableMap(
Map.Entry::getKey,
Map.Entry::getValue,
(v1, v2) -> v2 // in case of duplicate, ignore the v1
)));
}
/**
* @return an {@link Output} with an empty {@link Map}
* @see #ofMap(String, Object)
* @see #mapBuilder()
*/
static Output> ofMap() {
return Output.of(ImmutableMap.of());
}
/**
* @return an {@link Output} that wraps a {@link Map} with one pair.
* @see #mapBuilder()
*/
static Output> ofMap(String key1, V value1) {
return Output.of(ImmutableMap.of(key1, value1));
}
/**
* @return an {@link Output} that wraps a {@link Map} with two pairs.
* @see #ofMap(String, Object)
* @see #mapBuilder()
*/
static Output> ofMap(String key1, V value1,
String key2, V value2) {
return Output.of(ImmutableMap.of(key1, value1, key2, value2));
}
/**
* @return an {@link Output} that wraps a {@link Map} with three pairs.
* @see #ofMap(String, Object)
* @see #mapBuilder()
*/
static Output> ofMap(String key1, V value1,
String key2, V value2,
String key3, V value3) {
return Output.of(ImmutableMap.of(key1, value1, key2, value2, key3, value3));
}
/**
* @return an {@link Output} that wraps a {@link Map} with four pairs.
* @see #ofMap(String, Object)
* @see #mapBuilder()
*/
static Output> ofMap(String key1, V value1,
String key2, V value2,
String key3, V value3,
String key4, V value4) {
return Output.of(
ImmutableMap.of(key1, value1, key2, value2,
key3, value3, key4, value4));
}
/**
* @return an {@link Output} that wraps a {@link Map} with five pairs.
* @see #ofMap(String, Object)
* @see #mapBuilder()
*/
static Output> ofMap(String key1, V value1,
String key2, V value2,
String key3, V value3,
String key4, V value4,
String key5, V value5) {
return Output.of(
ImmutableMap.of(key1, value1, key2, value2,
key3, value3, key4, value4, key5, value5));
}
/**
* Helps to build a {@link Map} wrapped in an {@link Output}.
*
* @see #ofMap(String, Object)
*/
static Output.MapBuilder mapBuilder() {
return new Output.MapBuilder<>();
}
/**
* A {@link Map} wrapped in an {@link Output} builder.
*/
final class MapBuilder {
private final CompletableFutures.Builder>> builder;
public MapBuilder() {
builder = CompletableFutures.builder(
CompletableFuture.completedFuture(OutputData.builder(ImmutableMap.builder()))
);
}
@CanIgnoreReturnValue
public Output.MapBuilder put(String key, Output value) {
this.builder.accumulate(
Internal.of(value).getDataAsync(),
(dataBuilder, data) -> dataBuilder.accumulate(data,
(mapBuilder, v) -> mapBuilder.put(key, v))
);
return this;
}
@CanIgnoreReturnValue
public Output.MapBuilder put(String key, V value) {
this.builder.accumulate(
CompletableFuture.completedFuture(OutputData.of(value)),
(dataBuilder, data) -> dataBuilder.accumulate(data,
(mapBuilder, v) -> mapBuilder.put(key, v))
);
return this;
}
@CanIgnoreReturnValue
public Output.MapBuilder put(Map.Entry extends String, ? extends V> entry) {
this.builder.accumulate(
CompletableFuture.completedFuture(OutputData.of(entry)),
(dataBuilder, data) -> dataBuilder.accumulate(data, ImmutableMap.Builder::put)
);
return this;
}
@CanIgnoreReturnValue
public Output.MapBuilder putAll(Map extends String, ? extends V> map) {
this.builder.accumulate(
CompletableFuture.completedFuture(OutputData.of(map)),
(dataBuilder, data) -> dataBuilder.accumulate(data, ImmutableMap.Builder::putAll)
);
return this;
}
@SuppressWarnings("UnstableApiUsage")
@CanIgnoreReturnValue
public Output.MapBuilder putAll(Iterable extends Map.Entry extends String, ? extends V>> entries) {
this.builder.accumulate(
CompletableFuture.completedFuture(OutputData.of(entries)),
(dataBuilder, data) -> dataBuilder.accumulate(data, ImmutableMap.Builder::putAll)
);
return this;
}
public Output> build() {
return new OutputInternal<>(builder.build(dataBuilder -> dataBuilder.build(ImmutableMap.Builder::build)));
}
}
// Tuple Overloads that take various number of outputs.
/**
* @param type of {@code item1}
* @param type of {@code item2}
* @param item1 the 1st item ot the tuple
* @param item2 the 2nd item ot the tuple
* @return an {@link Output} holding a {@link Tuple2} with all given items
* @see Output#tuple(Output, Output, Output, Output, Output, Output, Output, Output)
*/
static Output> tuple(Output item1, Output item2) {
return tuple(item1, item2, TupleZeroOut, TupleZeroOut, TupleZeroOut, TupleZeroOut, TupleZeroOut, TupleZeroOut)
.applyValue(v -> Tuples.of(v.t1, v.t2));
}
/**
* @param type of {@code item1}
* @param type of {@code item2}
* @param type of {@code item3}
* @param item1 the 1st item ot the tuple
* @param item2 the 2nd item ot the tuple
* @param item3 the 3rd item ot the tuple
* @return an {@link Output} holding a {@link Tuple3} with all given items
* @see Output#tuple(Output, Output, Output, Output, Output, Output, Output, Output)
*/
static Output> tuple(
Output item1, Output item2, Output item3
) {
return tuple(item1, item2, item3, TupleZeroOut, TupleZeroOut, TupleZeroOut, TupleZeroOut, TupleZeroOut)
.applyValue(v -> Tuples.of(v.t1, v.t2, v.t3));
}
/**
* @param type of {@code item1}
* @param type of {@code item2}
* @param type of {@code item3}
* @param type of {@code item4}
* @param item1 the 1st item ot the tuple
* @param item2 the 2nd item ot the tuple
* @param item3 the 3rd item ot the tuple
* @param item4 the 4th item ot the tuple
* @return an {@link Output} holding a {@link Tuple4} with all given items
* @see Output#tuple(Output, Output, Output, Output, Output, Output, Output, Output)
*/
static Output> tuple(
Output item1, Output item2, Output item3, Output item4
) {
return tuple(item1, item2, item3, item4, TupleZeroOut, TupleZeroOut, TupleZeroOut, TupleZeroOut)
.applyValue(v -> Tuples.of(v.t1, v.t2, v.t3, v.t4));
}
/**
* @param type of {@code item1}
* @param type of {@code item2}
* @param type of {@code item3}
* @param type of {@code item4}
* @param type of {@code item5}
* @param item1 the 1st item ot the tuple
* @param item2 the 2nd item ot the tuple
* @param item3 the 3rd item ot the tuple
* @param item4 the 4th item ot the tuple
* @param item5 the 5th item ot the tuple
* @return an {@link Output} holding a {@link Tuple5} with all given items
* @see Output#tuple(Output, Output, Output, Output, Output, Output, Output, Output)
*/
static Output> tuple(
Output item1, Output item2, Output item3, Output item4,
Output item5
) {
return tuple(item1, item2, item3, item4, item5, TupleZeroOut, TupleZeroOut, TupleZeroOut)
.applyValue(v -> Tuples.of(v.t1, v.t2, v.t3, v.t4, v.t5));
}
/**
* @param type of {@code item1}
* @param type of {@code item2}
* @param type of {@code item3}
* @param type of {@code item4}
* @param type of {@code item5}
* @param type of {@code item6}
* @param item1 the 1st item ot the tuple
* @param item2 the 2nd item ot the tuple
* @param item3 the 3rd item ot the tuple
* @param item4 the 4th item ot the tuple
* @param item5 the 5th item ot the tuple
* @param item6 the 6th item ot the tuple
* @return an {@link Output} holding a {@link Tuple6} with all given items
* @see Output#tuple(Output, Output, Output, Output, Output, Output, Output, Output)
*/
static Output> tuple(
Output item1, Output item2, Output item3, Output item4,
Output item5, Output item6
) {
return tuple(item1, item2, item3, item4, item5, item6, TupleZeroOut, TupleZeroOut)
.applyValue(v -> Tuples.of(v.t1, v.t2, v.t3, v.t4, v.t5, v.t6));
}
/**
* @param type of {@code item1}
* @param type of {@code item2}
* @param type of {@code item3}
* @param type of {@code item4}
* @param type of {@code item5}
* @param type of {@code item6}
* @param type of {@code item7}
* @param item1 the 1st item ot the tuple
* @param item2 the 2nd item ot the tuple
* @param item3 the 3rd item ot the tuple
* @param item4 the 4th item ot the tuple
* @param item5 the 5th item ot the tuple
* @param item6 the 6th item ot the tuple
* @param item7 the 7th item ot the tuple
* @return an {@link Output} holding a {@link Tuple7} with all given items
* @see Output#tuple(Output, Output, Output, Output, Output, Output, Output, Output)
*/
static Output