All Downloads are FREE. Search and download functionalities are using the official Maven repository.

smithy4s.internals.DocumentKeyEncoder.scala Maven / Gradle / Ivy

There is a newer version: 0.19.0-41-91762fb
Show newest version
/*
 *  Copyright 2021-2024 Disney Streaming
 *
 *  Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     https://disneystreaming.github.io/TOST-1.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package smithy4s.internals

import smithy.api.TimestampFormat
import smithy.api.TimestampFormat._
import smithy4s._
import smithy4s.schema.EnumValue
import smithy4s.schema.Primitive
import smithy4s.schema.Primitive._
import smithy4s.schema.SchemaVisitor
import smithy4s.schema.Schema
import smithy4s.schema.EnumTag

trait DocumentKeyEncoder[A] { self =>
  def apply(a: A): String

  def contramap[B](f: B => A): DocumentKeyEncoder[B] =
    new DocumentKeyEncoder[B] {
      def apply(b: B): String = self(f(b))
    }
}

object DocumentKeyEncoder {
  type OptDocumentKeyEncoder[A] = Option[DocumentKeyEncoder[A]]
  val trySchemaVisitor: SchemaVisitor[OptDocumentKeyEncoder] =
    new SchemaVisitor.Default[OptDocumentKeyEncoder] {
      private def instance[A](f: A => String): OptDocumentKeyEncoder[A] = Some {
        a =>
          a.toString()
      }
      private def forBigDecimal[A](
          f: A => BigDecimal
      ): OptDocumentKeyEncoder[A] =
        Some { a =>
          a.toString()
        }
      private def asString[A]: OptDocumentKeyEncoder[A] = instance {
        _.toString()
      }
      def default[A]: OptDocumentKeyEncoder[A] = None

      override def primitive[P](
          shapeId: ShapeId,
          hints: Hints,
          tag: Primitive[P]
      ): OptDocumentKeyEncoder[P] = {
        tag match {
          case PBoolean    => asString
          case PBigDecimal => asString
          case PUUID       => asString
          case PString     => asString
          case PShort      => forBigDecimal { a => BigDecimal(a.toInt) }
          case PBigInt     => forBigDecimal { BigDecimal(_) }
          case PInt        => forBigDecimal { BigDecimal(_) }
          case PDouble     => forBigDecimal { BigDecimal(_) }
          case PLong       => forBigDecimal { BigDecimal(_) }
          case PByte       => forBigDecimal { a => BigDecimal(a.toInt) }
          case PFloat      => forBigDecimal { a => BigDecimal(a.toDouble) }
          case PBlob =>
            instance(_.toBase64String)
          case PTimestamp =>
            hints
              .get(TimestampFormat)
              .getOrElse(DATE_TIME) match {
              case DATE_TIME =>
                instance { ts => ts.format(DATE_TIME) }
              case HTTP_DATE =>
                instance { ts => ts.format(HTTP_DATE) }
              case EPOCH_SECONDS =>
                forBigDecimal { ts => BigDecimal(ts.epochSecond) }
            }
          case PDocument => None
        }
      }
      override def enumeration[E](
          shapeId: ShapeId,
          hints: Hints,
          tag: EnumTag[E],
          values: List[EnumValue[E]],
          total: E => EnumValue[E]
      ): OptDocumentKeyEncoder[E] = tag match {
        case EnumTag.IntEnum() =>
          Some { a => total(a).intValue.toString }
        case _ =>
          Some { a => total(a).stringValue }
      }

      override def biject[A, B](
          schema: Schema[A],
          bijection: Bijection[A, B]
      ): OptDocumentKeyEncoder[B] =
        apply(schema).map(_.contramap(bijection.from))

      override def refine[A, B](
          schema: Schema[A],
          refinement: Refinement[A, B]
      ): OptDocumentKeyEncoder[B] =
        apply(schema).map(_.contramap(refinement.from))
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy