001/*
002 * SPDX-License-Identifier: Apache-2.0
003 *
004 * Copyright 2025-2026 The Enola <https://enola.dev> Authors
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *     https://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package dev.enola.common.convert;
019
020import dev.enola.common.ByteSeq;
021import dev.enola.common.context.Context;
022import dev.enola.common.context.TLC;
023
024import io.ipfs.multibase.Multibase;
025
026import org.jspecify.annotations.Nullable;
027
028/**
029 * <a href="https://github.com/multiformats/multibase">Multibase</a> &lt;=&gt; {@link ByteSeq}
030 * Converter.
031 */
032final class MultibaseConverter implements ObjectToStringBiConverter<ByteSeq> {
033
034    // Currently implemented with https://github.com/multiformats/java-multibase;
035    // https://github.com/filip26/copper-multibase could be an alternative (if issues).
036
037    public enum Base implements Context.Key<Multibase.Base> {
038        DEFAULT
039    }
040
041    @Override
042    public @Nullable ByteSeq convertFrom(@Nullable String input) throws ConversionException {
043        if (input == null) return null;
044        try {
045            return ByteSeq.from(Multibase.decode(input));
046        } catch (Exception e) {
047            throw new ConversionException(input, e);
048        }
049    }
050
051    @Override
052    public @Nullable String convertTo(@Nullable ByteSeq input) throws ConversionException {
053        if (input == null) return null;
054        var base = TLC.optional(Base.DEFAULT).orElse(Multibase.Base.Base64Url);
055        return Multibase.encode(base, input.toBytes());
056    }
057}