nevillelyh/shapeless-datatype
{ "createdAt": "2016-10-07T17:27:01Z", "defaultBranch": "main", "description": "Shapeless utilities for common data types", "fullName": "nevillelyh/shapeless-datatype", "homepage": "", "language": "Scala", "name": "shapeless-datatype", "pushedAt": "2025-10-21T16:15:21Z", "stargazersCount": 67, "topics": [ "avro", "bigquery", "datastore", "google-cloud", "scala", "shapeless", "tensorflow" ], "updatedAt": "2025-10-21T16:15:25Z", "url": "https://github.com/nevillelyh/shapeless-datatype"}shapeless-datatype
Section titled “shapeless-datatype”Shapeless utilities for common data types. Also see Magnolify for a simpler and faster alternative based on Magnolia.
Modules
Section titled “Modules”This library includes the following modules.
shapeless-datatype-coreshapeless-datatype-avroshapeless-datatype-bigqueryshapeless-datatype-datastoreshapeless-datatype-tensorflow
Core includes the following components.
- A
MappableTypefor generic conversion between case class and other data types, used by BigQuery and Datastore modules. - A
RecordMapperfor generic conversion between case class types. - A
RecordMatcherfor generic type-based equality check bewteen case classes. - A
LensMatcherfor generic lens-based equality check between case classes.
RecordMapper
Section titled “RecordMapper”RecordMapper[A, B] maps instances of case class A and B with different field types.
import shapeless._import shapeless.datatype.record._import scala.language.implicitConversions
// records with same field names but different typescase class Point1(x: Double, y: Double, label: String)case class Point2(x: Float, y: Float, label: String)
// implicit conversion bewteen fields of different typesimplicit def f2d(x: Float) = x.toDoubleimplicit def d2f(x: Double) = x.toFloat
val m = RecordMapper[Point1, Point2]m.to(Point1(0.5, -0.5, "a")) // Point2(0.5,-0.5,a)m.from(Point2(0.5, -0.5, "a")) // Point1(0.5,-0.5,a)RecordMatcher
Section titled “RecordMatcher”RecordMatcher[T] performs equality check of instances of case class T with custom logic based on field types.
import shapeless.datatype.record._
case class Record(id: String, name: String, value: Int)
// custom comparator for String typeimplicit def compareStrings(x: String, y: String) = x.toLowerCase == y.toLowerCase
val m = RecordMatcher[Record]Record("a", "RecordA", 10) == Record("A", "RECORDA", 10) // false
// compareStrings is applied to all String fieldsm(Record("a", "RecordA", 10), Record("A", "RECORDA", 10)) // trueLensMatcher
Section titled “LensMatcher”LensMatcher[T] performs equality check of instances of case class T with custom logic based on Lenses.
import shapeless.datatype.record._
case class Record(id: String, name: String, value: Int)
// compare String fields id and name with different logicval m = LensMatcher[Record] .on(_ >> 'id)(_.toLowerCase == _.toLowerCase) .on(_ >> 'name)(_.length == _.length)
Record("a", "foo", 10) == Record("A", "bar", 10) // falsem(Record("a", "foo", 10), Record("A", "bar", 10)) // trueAvroType
Section titled “AvroType”AvroType[T] maps bewteen case class T and Avro GenericRecord. AvroSchema[T] generates schema for case class T.
import shapeless.datatype.avro._
case class City(name: String, code: String, lat: Double, long: Double)
val t = AvroType[City]val r = t.toGenericRecord(City("New York", "NYC", 40.730610, -73.935242))val c = t.fromGenericRecord(r)
AvroSchema[City]Custom types are also supported.
import shapeless.datatype.avro._import java.net.URIimport org.apache.avro.Schema
implicit val uriAvroType = AvroType.at[URI]!(Schema.Type.STRING)(v => URI.create(v.toString), _.toString)
case class Page(uri: URI, rank: Int)
val t = AvroType[Page]val r = t.toGenericRecord(Page(URI.create("www.google.com"), 42))val c = t.fromGenericRecord(r)
AvroSchema[Page]BigQueryType
Section titled “BigQueryType”BigQueryType[T] maps bewteen case class T and BigQuery TableRow. BigQuerySchema[T] generates schema for case class T.
import shapeless.datatype.bigquery._
case class City(name: String, code: String, lat: Double, long: Double)
val t = BigQueryType[City]val r = t.toTableRow(City("New York", "NYC", 40.730610, -73.935242))val c = t.fromTableRow(r)
BigQuerySchema[City]Custom types are also supported.
import shapeless.datatype.bigquery._import java.net.URI
implicit val uriBigQueryType = BigQueryType.at[URI]!("STRING")(v => URI.create(v.toString), _.toString)
case class Page(uri: URI, rank: Int)
val t = BigQueryType[Page]val r = t.toTableRow(Page(URI.create("www.google.com"), 42))val c = t.fromTableRow(r)
BigQuerySchema[Page]DatastoreType
Section titled “DatastoreType”DatastoreType[T] maps between case class T and Cloud Datastore Entity or Entity.Builder Protobuf types.
import shapeless.datatype.datastore._
case class City(name: String, code: String, lat: Double, long: Double)
val t = DatastoreType[City]val r = t.toEntity(City("New York", "NYC", 40.730610, -73.935242))val c = t.fromEntity(r)val b = t.toEntityBuilder(City("New York", "NYC", 40.730610, -73.935242))val d = t.fromEntityBuilder(b)Custom types are also supported.
import shapeless.datatype.datastore._import com.google.datastore.v1.client.DatastoreHelper._import java.net.URI
implicit val uriDatastoreType = DatastoreType.at[URI]!( v => URI.create(v.getStringValue), u => makeValue(u.toString).build())
case class Page(uri: URI, rank: Int)
val t = DatastoreType[Page]val r = t.toEntity(Page(URI.create("www.google.com"), 42))val c = t.fromEntity(r)val b = t.toEntityBuilder(Page(URI.create("www.google.com"), 42))val d = t.fromEntityBuilder(b)TensorFlowType
Section titled “TensorFlowType”TensorFlowType[T] maps between case class T and TensorFlow Example or Example.Builder Protobuf types.
import shapeless.datatype.tensorflow._
case class Data(floats: Array[Float], longs: Array[Long], strings: List[String], label: String)
val t = TensorFlowType[Data]val r = t.toExample(Data(Array(1.5f, 2.5f), Array(1L, 2L), List("a", "b"), "x"))val c = t.fromExample(r)val b = t.toExampleBuilder(Data(Array(1.5f, 2.5f), Array(1L, 2L), List("a", "b"), "x"))val d = t.fromExampleBuilder(b)Custom types are also supported.
import shapeless.datatype.tensorflow._import java.net.URI
implicit val uriTensorFlowType = TensorFlowType.at[URI]!( TensorFlowType.toStrings(_).map(URI.create), xs => TensorFlowType.fromStrings(xs.map(_.toString)))
case class Page(uri: URI, rank: Int)
val t = TensorFlowType[Page]val r = t.toExample(Page(URI.create("www.google.com"), 42))val c = t.fromExample(r)val b = t.toExampleBuilder(Page(URI.create("www.google.com"), 42))val d = t.fromExampleBuilder(b)License
Section titled “License”Copyright 2016 Neville Li.
Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0