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> <=> {@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}