001/* 002 * MIT License 003 * 004 * Copyright (c) 2024 Michael Cowan 005 * 006 * Permission is hereby granted, free of charge, to any person obtaining a copy 007 * of this software and associated documentation files (the "Software"), to deal 008 * in the Software without restriction, including without limitation the rights 009 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 010 * copies of the Software, and to permit persons to whom the Software is 011 * furnished to do so, subject to the following conditions: 012 * 013 * The above copyright notice and this permission notice shall be included in all 014 * copies or substantial portions of the Software. 015 * 016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 017 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 018 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 019 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 020 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 021 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 022 * SOFTWARE. 023 */ 024 025package io.blt.util; 026 027import java.util.Optional; 028 029/** 030 * Static utility methods for operating on {@code Enum}. 031 */ 032public final class En { 033 034 private En() { 035 throw new IllegalAccessError("Utility class should be accessed statically and never constructed"); 036 } 037 038 /** 039 * Returns the {@code enum} constant matching {@code name} as an {@link Optional}; otherwise, returns empty. 040 * The {@code name} must match exactly. 041 * <p> 042 * This method will not throw for an invalid enum name and instead will return empty. 043 * </p> 044 * e.g., 045 * <pre>{@code 046 * of(DayOfWeek.class, "FRIDAY"); // Optional.of(DayOfWeek.FRIDAY) 047 * of(DayOfWeek.class, "friday"); // Optional.empty() 048 * of(DayOfWeek.class, "Worf"); // Optional.empty() 049 * of(DayOfWeek.class, ""); // Optional.empty() 050 * }</pre> 051 * 052 * @param type The {@link Class} object of the enum class 053 * @param name The name of the constant to return 054 * @param <E> The type of the {@code Enum} 055 * @return an {@code Optional} containing the {@code enum} constant if found 056 * @throws NullPointerException if {@code type} or {@code name} is {@code null} 057 */ 058 public static <E extends Enum<E>> Optional<E> of(Class<E> type, String name) { 059 try { 060 return Optional.of(Enum.valueOf(type, name)); 061 } catch (IllegalArgumentException ignore) { 062 return Optional.empty(); 063 } 064 } 065 066 /** 067 * Returns the {@code enum} constant matching {@code name} as an {@link Optional}; otherwise, returns empty. 068 * The {@code name} comparison is case-insensitive. 069 * <p> 070 * This method will not throw for an invalid enum name and instead will return empty. 071 * </p> 072 * <pre>{@code 073 * ofIgnoreCase(DayOfWeek.class, "FRIDAY"); // Optional.of(DayOfWeek.FRIDAY) 074 * ofIgnoreCase(DayOfWeek.class, "friday"); // Optional.of(DayOfWeek.FRIDAY) 075 * ofIgnoreCase(DayOfWeek.class, "Worf"); // Optional.empty() 076 * ofIgnoreCase(DayOfWeek.class, ""); // Optional.empty() 077 * }</pre> 078 * 079 * @param type The {@link Class} object of the enum class 080 * @param name The name of the constant to return 081 * @param <E> The type of the {@code Enum} 082 * @return an {@code Optional} containing the {@code enum} constant if found 083 * @throws NullPointerException if {@code type} or {@code name} is {@code null} 084 */ 085 public static <E extends Enum<E>> Optional<E> ofIgnoreCase(Class<E> type, String name) { 086 for (var element : type.getEnumConstants()) { 087 if (name.equalsIgnoreCase(element.name())) { 088 return Optional.of(element); 089 } 090 } 091 return Optional.empty(); 092 } 093 094}