001/*
002 * Copyright 2022-2025 Revetware LLC.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.soklet;
018
019import javax.annotation.Nonnull;
020
021import static java.util.Objects.requireNonNull;
022
023/**
024 * Contract for generating identifiers of a particular type (for example, sequential {@link Long} values, random {@link java.util.UUID}s, etc.)
025 * <p>
026 * Implementations may or may not guarantee uniqueness, ordering, or repeatability of generated identifiers. Callers should not assume any such guarantees unless documented by the implementation.
027 * <p>
028 * Standard implementations can be acquired via these factory methods:
029 * <ul>
030 *   <li>{@link #withDefaults()}</li>
031 *   <li>{@link #withPrefix(String)}</li>
032 *   <li>{@link #withRange(Long, Long)} </li>
033 *   <li>{@link #withRangeAndPrefix(Long, Long, String)}</li>
034 * </ul>
035 *
036 * @param <T> the type of identifier produced
037 * @author <a href="https://www.revetkn.com">Mark Allen</a>
038 */
039@FunctionalInterface
040public interface IdGenerator<T> {
041        /**
042         * Generates an identifier.
043         * <p>
044         * Implementations may choose different strategies (sequential, random, host-based, etc.) and are not required to guarantee uniqueness unless explicitly documented.
045         *
046         * @return the generated identifier (never {@code null})
047         */
048        @Nonnull
049        T generateId();
050
051        /**
052         * Acquires an {@link IdGenerator} with a default numeric ID range (values will wrap once maximum is reached) and a best-effort local IP prefix.
053         * <p>
054         * Callers should not rely on reference identity; this method may return a new or cached instance.
055         *
056         * @return an {@code IdGenerator} with default settings
057         */
058        @Nonnull
059        static IdGenerator withDefaults() {
060                return DefaultIdGenerator.withDefaults();
061        }
062
063        /**
064         * Acquires an {@link IdGenerator} with the given minimum and maximum ID values (values will wrap once maximum is reached), and a best-effort local IP prefix.
065         * <p>
066         * Callers should not rely on reference identity; this method may return a new or cached instance.
067         *
068         * @param minimumId the lowest ID that may be generated (inclusive)
069         * @param maximumId the highest ID that may be generated (inclusive)
070         * @return an {@code IdGenerator} configured with the given range
071         */
072        @Nonnull
073        static IdGenerator withRange(@Nonnull Long minimumId,
074                                                                                                                         @Nonnull Long maximumId) {
075                requireNonNull(minimumId);
076                requireNonNull(maximumId);
077                return DefaultIdGenerator.withRange(minimumId, maximumId);
078        }
079
080        /**
081         * Returns a {@link DefaultIdGenerator} with the given minimum and maximum ID values (values will wrap once maximum is reached), and the specified prefix.
082         * <p>
083         * Callers should not rely on reference identity; this method may return a new or cached instance.
084         *
085         * @param minimumId the lowest ID that may be generated (inclusive)
086         * @param maximumId the highest ID that may be generated (inclusive)
087         * @param prefix    a string to prepend to the generated numeric ID
088         * @return an {@code IdGenerator} configured with the given range and prefix
089         */
090        @Nonnull
091        static IdGenerator withRangeAndPrefix(@Nonnull Long minimumId,
092                                                                                                                                                                @Nonnull Long maximumId,
093                                                                                                                                                                @Nonnull String prefix) {
094                requireNonNull(minimumId);
095                requireNonNull(maximumId);
096                requireNonNull(prefix);
097                return DefaultIdGenerator.withRangeAndPrefix(minimumId, maximumId, prefix);
098        }
099
100        /**
101         * Acquires an {@link IdGenerator} with a default numeric ID range (values will wrap once maximum is reached) and the given prefix.
102         * <p>
103         * Callers should not rely on reference identity; this method may return a new or cached instance.
104         *
105         * @param prefix a string to prepend to the generated numeric ID
106         * @return an {@code IdGenerator} configured with the given prefix
107         */
108        @Nonnull
109        static IdGenerator withPrefix(@Nonnull String prefix) {
110                requireNonNull(prefix);
111                return DefaultIdGenerator.withPrefix(prefix);
112        }
113}