2424package org .kitteh .irc .client .library .feature ;
2525
2626import org .jspecify .annotations .NonNull ;
27+ import org .jspecify .annotations .NullMarked ;
2728import org .jspecify .annotations .Nullable ;
2829import org .kitteh .irc .client .library .util .Sanity ;
2930
3031import java .util .HashMap ;
32+ import java .util .Locale ;
3133import java .util .Map ;
3234import java .util .Optional ;
3335
3436/**
3537 * ISUPPORT CASEMAPPING.
3638 */
37- public enum CaseMapping {
39+ @ NullMarked
40+ public interface CaseMapping {
41+ record Ranged (char upperbound ) implements CaseMapping {
42+ @ Override
43+ public String toLowerCase (String input ) {
44+ Sanity .nullCheck (input , "Input" );
45+ char [] arr = input .toCharArray ();
46+ for (int i = 0 ; i < arr .length ; i ++) {
47+ char c = arr [i ];
48+ if ((c >= 'A' ) && (c <= this .upperbound )) {
49+ arr [i ] += (char ) 32 ;
50+ }
51+ }
52+ return new String (arr );
53+ }
54+ }
55+
3856 /**
3957 * A-Z become a-z
4058 */
41- ASCII ('Z' ),
59+ CaseMapping . Ranged ASCII = new CaseMapping . Ranged ('Z' );
4260 /**
4361 * A-Z become a-z, []^ become {}~
4462 */
45- RFC1459 ('^' ),
63+ CaseMapping . Ranged RFC1459 = new CaseMapping . Ranged ('^' );
4664 /**
4765 * A-Z become a-z, [] become {}
4866 */
49- STRICT_RFC1459 (']' );
50-
51- private static final Map <String , CaseMapping > nameMap = new HashMap <>();
52-
53- static {
54- for (CaseMapping caseMapping : CaseMapping .values ()) {
55- CaseMapping .nameMap .put (caseMapping .name ().replace ('_' , '-' ), caseMapping );
56- }
57- }
58-
59- /**
60- * Gets a CaseMapping by name. Case insensitive.
61- *
62- * @param name the name of the CaseMapping to get
63- * @return the matching CaseMapping if one exists
64- */
65- public static @ NonNull Optional <CaseMapping > getByName (@ Nullable String name ) {
66- return (name == null ) ? Optional .empty () : Optional .ofNullable (CaseMapping .nameMap .get (name .toUpperCase ()));
67- }
68-
69- private final char upperbound ;
70-
71- CaseMapping (char upperbound ) {
72- this .upperbound = upperbound ;
73- }
67+ CaseMapping .Ranged STRICT_RFC1459 = new CaseMapping .Ranged (']' );
7468
75- /**
76- * Gets if two given strings are equal, case insensitive, using this
77- * case mapping.
78- *
79- * @param one one string
80- * @param two two string, red string, blue string
81- * @return true if equal ignoring case using this case mapping
82- */
83- public boolean areEqualIgnoringCase (@ NonNull String one , @ NonNull String two ) {
69+ default boolean areEqualIgnoringCase (String one ,String two ) {
8470 return this .toLowerCase (one ).equals (this .toLowerCase (two ));
8571 }
8672
@@ -91,15 +77,23 @@ public boolean areEqualIgnoringCase(@NonNull String one, @NonNull String two) {
9177 * @return lowercased string
9278 * @throws IllegalArgumentException if input is null
9379 */
94- public @ NonNull String toLowerCase (@ NonNull String input ) {
95- Sanity .nullCheck (input , "Input" );
96- char [] arr = input .toCharArray ();
97- for (int i = 0 ; i < arr .length ; i ++) {
98- char c = arr [i ];
99- if ((c >= 'A' ) && (c <= this .upperbound )) {
100- arr [i ] += (char ) 32 ;
101- }
80+ String toLowerCase (String input );
81+
82+ /**
83+ * Gets a CaseMapping by name, case-insensitive.
84+ *
85+ * @param name the name of the CaseMapping to get
86+ * @return the matching CaseMapping if one exists
87+ */
88+ static @ NonNull Optional <CaseMapping > getByName (@ Nullable String name ) {
89+ if (name == null ) {
90+ return Optional .empty ();
10291 }
103- return new String (arr );
92+ return Optional .ofNullable (switch (name .toUpperCase (Locale .ROOT )) {
93+ case "ASCII" -> ASCII ;
94+ case "RFC1459" -> RFC1459 ;
95+ case "STRICT-RFC1459" -> STRICT_RFC1459 ;
96+ default -> null ;
97+ });
10498 }
10599}
0 commit comments