MessageImpl.java

/*
 * SPDX-FileCopyrightText: 2025 kaumei.io
 * SPDX-License-Identifier: Apache-2.0
 */
package io.kaumei.jdbc.anno.msg;

import org.jspecify.annotations.Nullable;

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.function.Supplier;

import static java.util.Objects.requireNonNull;

sealed class MessageImpl implements Msg.Message
        permits JdbcMsg.InvalidParamConverter, JdbcMsg.InvalidReturnConverter {

    private final String text;

    @SuppressWarnings("ConstantConditions")
    MessageImpl(String text) {
        if (text == null) {
            throw new IllegalArgumentException("text must not be null");
        } else if (text.isBlank()) {
            throw new IllegalArgumentException("text must not be blank");
        }
        this.text = text;
    }

    @Override
    public String toString() {
        return '[' + text + ']';
    }

    // interface Iterable<Msg.Message> ----------------------------------------

    @Override
    public boolean equals(@Nullable Object o) {
        if (this == o) {
            return true;
        } else if (o == null || getClass() != o.getClass()) {
            return false;
        }
        return text.equals(((MessageImpl) o).text);
    }

    @Override
    public int hashCode() {
        return this.text.hashCode();
    }

    @Override
    public Iterator<Msg.Message> iterator() {
        return new LocalIterator();
    }

    // interface Msg.Messages -------------------------------------------------

    @Override
    public String text() {
        return this.text;
    }

    @Override
    public boolean hasMessages() {
        return true;
    }

    @Override
    public boolean hasNoMessages() {
        return false;
    }

    @Override
    public String join(String sep) {
        return text;
    }

    @Override
    public void join(StringBuilder sb, String sep) {
        sb.append(text);
    }

    @Override
    public void requireEmpty() {
        throw new IllegalStateException("List not empty: " + text);
    }

    @Override
    public Msg.Messages requireNoneEmpty() {
        return this;
    }

    @Override
    public <T> Msg.Result<T> build(T value) {
        requireNonNull(value, "value");
        return new MessageResultImpl<>(this);
    }

    @Override
    public <T> Msg.Result<T> build(Supplier<T> func) {
        requireNonNull(func, "func");
        return new MessageResultImpl<>(this);
    }

    @Override
    public <T> Msg.NullableResult<T> buildOpt(@Nullable T value) {
        return new MessageResultNullableImpl<>(this);
    }

    // interface Comparable<Msg.Message> --------------------------------------

    @Override
    public int compareTo(Msg.Message o) {
        return text.compareTo(o.text());
    }

    // ------------------------------------------------------------------------

    private final class LocalIterator implements Iterator<Msg.Message> {
        boolean next = true;

        @Override
        public boolean hasNext() {
            return next;
        }

        @Override
        public Msg.Message next() {
            if (!next) {
                throw new NoSuchElementException();
            }
            next = false;
            return MessageImpl.this;
        }
    }

}