package org.adridadou.openlaw.parser.template.variableTypes import cats.implicits._ import io.circe.{Decoder, Encoder} import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} import io.circe.parser.decode import org.adridadou.openlaw.{OpenlawNativeValue, OpenlawString, OpenlawValue} import org.adridadou.openlaw.parser.template.formatters.Formatter import org.adridadou.openlaw.parser.template._ import org.adridadou.openlaw.parser.template.expressions.Expression import org.adridadou.openlaw.result.{Failure, FailureException, Result, Success} object LinkInfo { implicit val linkInfoEnc: Encoder[LinkInfo] = deriveEncoder implicit val linkInfoDec: Decoder[LinkInfo] = deriveDecoder } final case class LinkInfo(label: String, url: String) extends OpenlawNativeValue case object LinkType extends VariableType(name = "Link") with NoShowInFormButRender { override def cast( value: String, executionResult: TemplateExecutionResult ): Result[LinkInfo] = decode[LinkInfo](value).leftMap(FailureException(_)) override def internalFormat(value: OpenlawValue): Result[String] = VariableType.convert[OpenlawString](value) override def defaultFormatter: Formatter = new LinkFormatter override def getTypeClass: Class[LinkInfo] = classOf[LinkInfo] override def construct( constructorParams: Parameter, executionResult: TemplateExecutionResult ): Result[Option[LinkInfo]] = constructorParams match { case Parameters(seq) => val map = seq.toMap for { label <- map.get("label").traverse(getOneValueConstant) url <- map.get("url").traverse(getOneValueConstant) } yield (label, url) mapN { LinkInfo(_, _) } case _ => Failure("""Link requires parameters, not a unique value or a list""") } def thisType: VariableType = LinkType private def getOneValueConstant(value: Parameter): Result[String] = value match { case OneValueParameter(StringConstant(v)) => Success(v) case _ => Failure("""Link requires "label" argument.""") } } class LinkFormatter extends Formatter { override def format( expression: Expression, value: OpenlawValue, executionResult: TemplateExecutionResult ): Result[List[AgreementElement]] = VariableType.convert[LinkInfo](value) map { case LinkInfo(labelValue, urlValue) => List(Link(labelValue, urlValue)) } override def missingValueFormat( expression: Expression ): List[AgreementElement] = List(FreeText(Text(s"[[$expression]]"))) override def stringFormat( expression: Expression, value: OpenlawValue, executionResult: TemplateExecutionResult ): Result[String] = VariableType.convert[LinkInfo](value) map { case LinkInfo(labelValue, urlValue) => s"$labelValue[$urlValue]" } }