View Javadoc
1   package dev.sympho.modular_commands.api.command.parameter;
2   
3   import javax.annotation.Nullable;
4   
5   import org.checkerframework.checker.nullness.qual.NonNull;
6   import org.checkerframework.checker.regex.qual.Regex;
7   import org.checkerframework.common.value.qual.MatchesRegex;
8   import org.checkerframework.dataflow.qual.Pure;
9   import org.checkerframework.dataflow.qual.SideEffectFree;
10  import org.immutables.value.Value;
11  
12  import dev.sympho.modular_commands.api.command.Command;
13  import dev.sympho.modular_commands.api.command.parameter.parse.ArgumentParser;
14  import dev.sympho.modular_commands.utils.ParameterUtils;
15  
16  // BEGIN LONG LINES
17  /**
18   * Specification for a parameter received for a command.
19   * 
20   * <p>Irrespective of whether the command it is used with is compatible with interactions
21   * or not, all values must be compatible with the
22   * <a href="https://discord.com/developers/docs/interactions/application-commands#application-command-object">
23   * Discord API specification</a> for command parameters.
24   *
25   * @param <T> The type of argument that is provided.
26   * @version 1.0
27   * @since 1.0
28   */
29  // END LONG LINES
30  @Value.Immutable
31  @Value.Style( 
32          visibility = Value.Style.ImplementationVisibility.PACKAGE, 
33          overshadowImplementation = true
34  )
35  public interface Parameter<T extends @NonNull Object> {
36  
37      /** Pattern for valid parameter names in the Discord API. */
38      @Regex String NAME_REGEX = Command.NAME_REGEX;
39      /** Pattern for valid parameter descriptions in the Discord API. */
40      @Regex String DESCRIPTION_REGEX = Command.DESCRIPTION_REGEX;
41  
42      /**
43       * The name of the parameter.
44       *
45       * @return The value.
46       */
47      @Pure
48      @MatchesRegex( NAME_REGEX ) String name();
49  
50      /**
51       * The description of the parameter.
52       *
53       * @return The value.
54       */
55      @Pure
56      @MatchesRegex( DESCRIPTION_REGEX ) String description();
57  
58      /**
59       * Whether the parameter must be provided to invoke the command.
60       *
61       * @return The value.
62       * @implSpec The default is {@code false}.
63       */
64      @Pure
65      @Value.Default
66      default boolean required() {
67          return false;
68      }
69  
70      /**
71       * The default value for the parameter.
72       * 
73       * <p>If {@code null}, the parameter has no default and will be {@code null} if missing.
74       * 
75       * <p>Note that this property is only meaningful if {@link #required()} is {@code false}.
76       *
77       * @return The value.
78       * @implSpec The default is {@code null}.
79       */
80      @Pure
81      // TODO: Replace JSR305 @Nullable with Checker's 
82      // Blocked by https://github.com/immutables/immutables/issues/1262
83      @Nullable T defaultValue();
84  
85      /**
86       * The parser to use to process received arguments.
87       *
88       * @return The value.
89       */
90      @Pure
91      ArgumentParser<?, T> parser();
92  
93      /**
94       * Validates that the properties of this instance are valid.
95       *
96       * @throws IllegalArgumentException if any of properties are invalid.
97       * @throws NullPointerException if a {@code null} value was found where not allowed.
98       * @see ParameterUtils#validate(Parameter)
99       */
100     @Pure
101     @Value.Check
102     default void validate() throws IllegalArgumentException, NullPointerException {
103 
104         ParameterUtils.validate( this );
105 
106     }
107 
108     /**
109      * Creates a new builder.
110      *
111      * @param <T> The argument type.
112      * @return The builder.
113      */
114     @SideEffectFree
115     static <T extends @NonNull Object> Builder<T> builder() {
116         return new Builder<>();
117     }
118 
119     /**
120      * Creates a new builder initialized with the properties of the given parameter.
121      *
122      * @param <T> The argument type.
123      * @param base The base instance to copy.
124      * @return The builder.
125      */
126     @SideEffectFree
127     static <T extends @NonNull Object> Builder<T> builder( final Parameter<T> base ) {
128         return new Builder<T>().from( base );
129     }
130 
131     /**
132      * The default builder.
133      *
134      * @param <T> The argument type.
135      * @since 1.0
136      */
137     @SuppressWarnings( "MissingCtor" )
138     class Builder<T extends @NonNull Object> extends ImmutableParameter.Builder<T> {}
139 
140 }