From 9aa5275f1829ce3cfeddadd63792dc71374e8632 Mon Sep 17 00:00:00 2001 From: Riley Park Date: Sun, 23 May 2021 00:31:54 -0700 Subject: [PATCH] feat(api/text) #378: ability to unset decorations during component construction --- .../adventure/text/format/TextDecoration.java | 22 ++++++ .../text/format/TextDecorationAndState.java | 67 ++++++++++++++++++ .../format/TextDecorationAndStateImpl.java | 68 +++++++++++++++++++ .../adventure/text/format/StyleTest.java | 28 ++++++++ 4 files changed, 185 insertions(+) create mode 100644 api/src/main/java/net/kyori/adventure/text/format/TextDecorationAndState.java create mode 100644 api/src/main/java/net/kyori/adventure/text/format/TextDecorationAndStateImpl.java diff --git a/api/src/main/java/net/kyori/adventure/text/format/TextDecoration.java b/api/src/main/java/net/kyori/adventure/text/format/TextDecoration.java index c97364574..915629f44 100644 --- a/api/src/main/java/net/kyori/adventure/text/format/TextDecoration.java +++ b/api/src/main/java/net/kyori/adventure/text/format/TextDecoration.java @@ -77,6 +77,28 @@ public enum TextDecoration implements StyleBuilderApplicable, TextFormat { this.name = name; } + /** + * Creates a {@link TextDecorationAndState}. + * + * @param state the state + * @return a {@link TextDecorationAndState} + * @since 4.8.0 + */ + public final @NotNull TextDecorationAndState as(final boolean state) { + return this.as(State.byBoolean(state)); + } + + /** + * Creates a {@link TextDecorationAndState}. + * + * @param state the state + * @return a {@link TextDecorationAndState} + * @since 4.8.0 + */ + public final @NotNull TextDecorationAndState as(final @NotNull State state) { + return new TextDecorationAndStateImpl(this, state); + } + @Override public void styleApply(final Style.@NotNull Builder style) { style.decorate(this); diff --git a/api/src/main/java/net/kyori/adventure/text/format/TextDecorationAndState.java b/api/src/main/java/net/kyori/adventure/text/format/TextDecorationAndState.java new file mode 100644 index 000000000..419ec8a52 --- /dev/null +++ b/api/src/main/java/net/kyori/adventure/text/format/TextDecorationAndState.java @@ -0,0 +1,67 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2021 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.format; + +import java.util.stream.Stream; +import net.kyori.examination.Examinable; +import net.kyori.examination.ExaminableProperty; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.jetbrains.annotations.ApiStatus; + +/** + * A combination of a {@link TextDecoration} and a {@link TextDecoration.State}. + * + * @since 4.8.0 + */ +@ApiStatus.NonExtendable +public interface TextDecorationAndState extends Examinable, StyleBuilderApplicable { + /** + * Gets the decoration. + * + * @return the decoration + * @since 4.8.0 + */ + @NonNull TextDecoration decoration(); + + /** + * Gets the state. + * + * @return the state + * @since 4.8.0 + */ + TextDecoration.@NonNull State state(); + + @Override + default void styleApply(final Style.@NonNull Builder style) { + style.decoration(this.decoration(), this.state()); + } + + @Override + default @NonNull Stream examinableProperties() { + return Stream.of( + ExaminableProperty.of("decoration", this.decoration()), + ExaminableProperty.of("state", this.state()) + ); + } +} diff --git a/api/src/main/java/net/kyori/adventure/text/format/TextDecorationAndStateImpl.java b/api/src/main/java/net/kyori/adventure/text/format/TextDecorationAndStateImpl.java new file mode 100644 index 000000000..148175a62 --- /dev/null +++ b/api/src/main/java/net/kyori/adventure/text/format/TextDecorationAndStateImpl.java @@ -0,0 +1,68 @@ +/* + * This file is part of adventure, licensed under the MIT License. + * + * Copyright (c) 2017-2021 KyoriPowered + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.kyori.adventure.text.format; + +import net.kyori.examination.string.StringExaminer; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +final class TextDecorationAndStateImpl implements TextDecorationAndState { + private final TextDecoration decoration; + private final TextDecoration.State state; + + TextDecorationAndStateImpl(final TextDecoration decoration, final TextDecoration.State state) { + this.decoration = decoration; + this.state = state; + } + + @Override + public @NonNull TextDecoration decoration() { + return this.decoration; + } + + @Override + public TextDecoration.@NonNull State state() { + return this.state; + } + + @Override + public String toString() { + return this.examine(StringExaminer.simpleEscaping()); + } + + @Override + public boolean equals(final @Nullable Object other) { + if (this == other) return true; + if (other == null || this.getClass() != other.getClass()) return false; + final TextDecorationAndStateImpl that = (TextDecorationAndStateImpl) other; + return this.decoration == that.decoration && this.state == that.state; + } + + @Override + public int hashCode() { + int result = this.decoration.hashCode(); + result = (31 * result) + this.state.hashCode(); + return result; + } +} diff --git a/api/src/test/java/net/kyori/adventure/text/format/StyleTest.java b/api/src/test/java/net/kyori/adventure/text/format/StyleTest.java index 8e3eeaf02..e42fe3caa 100644 --- a/api/src/test/java/net/kyori/adventure/text/format/StyleTest.java +++ b/api/src/test/java/net/kyori/adventure/text/format/StyleTest.java @@ -87,6 +87,34 @@ void testOfApplicables() { assertEquals(s0, s1); } + @Test + void testOfTextDecorationAndState() { + final Style s0 = Style.style( + TextDecoration.BOLD.as(TextDecoration.State.TRUE), + TextDecoration.ITALIC.as(TextDecoration.State.FALSE) + ); + assertDecorations(s0, ImmutableSet.of(TextDecoration.BOLD), ImmutableSet.of(TextDecoration.ITALIC)); + final Style s1 = Style.style( + TextDecoration.BOLD.as(true), + TextDecoration.ITALIC.as(false) + ); + assertDecorations(s1, ImmutableSet.of(TextDecoration.BOLD), ImmutableSet.of(TextDecoration.ITALIC)); + } + + @Test + void testOfTextDecorationAndStateOverridesWhenSame() { + final Style s0 = Style.style( + TextDecoration.BOLD.as(TextDecoration.State.TRUE), + TextDecoration.BOLD.as(TextDecoration.State.FALSE) + ); + assertDecorations(s0, ImmutableSet.of(), ImmutableSet.of(TextDecoration.BOLD)); + final Style s1 = Style.style( + TextDecoration.BOLD.as(true), + TextDecoration.BOLD.as(false) + ); + assertDecorations(s1, ImmutableSet.of(), ImmutableSet.of(TextDecoration.BOLD)); + } + @Test void testOfColor() { assertSame(Style.empty(), Style.style((TextColor) null));