Skip to content

halotukozak/mcodec

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

59 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mcodec

GenCodec-style serialization for Scala 3 — a format-agnostic, streaming Input/Output core with type class derivation built on M&DE. Ships with a JSON backend.

Experimental. Pinned to Scala 3.8.4 (Scala Next), required by Made (made_3:0.1.2). JVM only.

Overview

mcodec is a serialization library in the spirit of AVSystem GenCodec: a single MCodec[T] type class both reads and writes, and the wire format is decoupled from the codecs. Codecs talk to an abstract streaming Input/Output, so the same MCodec[T] works across any backend that implements those.

  • One type class for read and writeMCodec[T] with read(input) / write(output, value)
  • Format-agnostic core — codecs target a streaming Input/Output; the JSON backend is just one implementation
  • Automatic derivationderives MCodec for case classes, enums, and sealed hierarchies, powered by M&DE mirrors
  • Annotation-aware@name to rename fields and ADT cases on the wire, @flatten / @defaultCase for ADTs
  • Combinatorstransform, transformed, nullable, and makeLazy for building codecs from existing ones
  • Explicit nulls — compiled with -Yexplicit-nulls; nullability is expressed in the types

Built-in codecs cover the primitives, BigInt/BigDecimal, UUID, Option, Either, tuples, and the common collections (List, Vector, Seq, Set, Map).

Installation

mcodec has not had its first release yet. The coordinates below are how it will be published to Maven Central under io.github.halotukozak once tagged. Until then, build from source (see Build).

scala-cli

//> using scala 3.8.4
//> using dep io.github.halotukozak::mcodec::<version>

sbt

scalaVersion := "3.8.4"
libraryDependencies += "io.github.halotukozak" %% "mcodec" % "<version>"

mill

def scalaVersion = "3.8.4"
def mvDeps = Seq(mvn"io.github.halotukozak::mcodec::<version>")

Quickstart

Derive an MCodec for a case class and round-trip it through JSON.

import mcodec.*

case class User(name: String, age: Int) derives MCodec

val json = Json.write(User("Alice", 30)) // {"name":"Alice","age":30}
val user = Json.read[User](json) // User("Alice", 30)

Rename fields and ADT cases on the wire with @name:

import mcodec.*
import made.annotation.name

case class User(@name("user_name") name: String, age: Int) derives MCodec

enum Shape derives MCodec:
  @name("circ") case Circle(radius: Double)

Json.write(User("bob", 30)) // {"user_name":"bob","age":30}
Json.write[Shape](Shape.Circle(2.0)) // {"circ":{"radius":2.0}}

Build codecs from existing ones with the combinators on MCodec:

import mcodec.*

opaque type Email = String
given MCodec[Email] = MCodec[String].transform(identity, identity)

val nullableInt: MCodec[Int | Null] = MCodec[Int].nullable

Build

scala-cli --power compile .
scala-cli --power test .
scala-cli --power fmt .

Acknowledgements

mcodec is inspired by the AVSystem commons by **ghik **, whose GenCodec is the model for the codec design

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages