circe-literal-extras

Compile time literal json validator supporting inlined values based on type schema.

An extra module for JSON library for Scala circe. Supported Scala versions include 3.0.0-M3.

Here's a quick example of circe-literal-extras in action:

Define custom type schema (in a separate file):

case class Buzz(int: Int, bool: Boolean)
case class Bar(str: String, bool: Boolean)
case class Foo(int: Int, bar: Option[Bar], buzzes: List[Buzz])

Define custom string interpolation prefix:

import group.scala.karazin.circe.literal.extras._

extension (inline sc: StringContext)
  inline def encode(inline args: Any*): Json = // Custom "encode" string interpolation prefix
    ${ macros.encode[Foo]('sc, 'args) } // Macros with `Foo` type schema

The following interpolated strings are successfully verified on compile time. circe json encoders for inlined values are required.

val rawJson: Json =
    encode"""
          {
            "int": 42,
            "bar": {
              "str": "str",
              "bool": true
             },
            "buzzes": [
              {
                "int": 42,
                "bool": true
              },
              {
                "int": 42,
                "bool": false
              }
            ]
          }
          """
          

val bool: Boolean = ...

val booleanInlinedJson: Json =
    encode"""
            {
              "int": 42,
              "bar": {
                "str": "str",
                "bool": $bool
               },
              "buzzes": [
                {
                  "int": 42,
                  "bool": $bool
                },
                {
                  "int": 42,
                  "bool": $bool
                }
              ]
            }
            """
            

val int: Int = ...

val intInlinedJson: Json =
    encode"""
            {
              "int": $int,
              "bar": {
                "str": "str",
                "bool": true
               },
              "buzzes": [
                {
                  "int": $int,
                  "bool": true
                },
                {
                  "int": $int,
                  "bool": false
                }
              ]
            }
            """
           

val str: String = ...

val stringInlinedJson: Json =
    encode"""
            {
              "int": 42,
              "bar": {
                "str": $str,
                "bool": true
               },
              "buzzes": [
                {
                  "int": 42,
                  "bool": true
                },
                {
                  "int": 42,
                  "bool": false
                }
              ]
            }
            """
            
val buzzes: List[Buzz] = ...

val buzzesInlinedJson: Json =
    encode"""
            {
              "int": 42,
              "bar": {
                "str": "str",
                "bool": true
               },
              "buzzes": $buzzes
            }
            """
   
val bar: Bar = ...

val barInlinedJson: Json =
    encode"""
            {
              "int": 42,
              "bar": $bar,
              "buzzes": [
                {
                  "int": 42,
                  "bool": true
                },
                {
                  "int": 42,
                  "bool": false
                }
              ]
            }
            """

val foo: Foo = ...

val fooInlinedJson: Json =
    encode"""
            $foo
            """

It is not required to use the same types as defined in type schema. The types which preserve the type schema are also accepted:

case class BuzzLike(int: Int, bool: Boolean)
case class BarLike(str: String, bool: Boolean)
case class FooLike(int: Int, bar: BarLike, buzzes: List[BuzzLike]) // `bar` is required 

...

val fooLike: FooLike = ...

val fooLikeInlinedJson: Json =
    encode"""
            $fooLike
            """

License

circe-literal-extras is licensed under the Apache License, Version 2.0 (the "License"); you may not use this software except in compliance with the License.

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.