Home

Awesome

<!-- Copyright 2016-2020 Daniel Urban and contributors listed in AUTHORS Copyright 2020 Nokia SPDX-License-Identifier: Apache-2.0 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 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. --->

seals

Latest version

seals is an experimental project by Daniel Urban, which provides tools for schema evolution and language-integrated schemata.

By using it, you will be able to

Since it's a fairly new project, not all of these features are implemented yet. Bugs are to be expected as well. Contributions to improve the project, and reports about issues you encounter are welcome.

Getting started

seals is currently available for Scala 2.12 and 2.13. JARs are available on Maven Central. To use it, put this into your build.sbt (see below for the available modules):

libraryDependencies += "dev.tauri" %% "seals-core" % "0.4.0-RC2"

All releases (and commits on the master branch) are signed by key 36A8 2002 483A 4CBF A5F8 DF6F 48B2 9573 BF19 7B13.

Features

Defining schemata

By using seals-core, you can define a schema simply by creating an ADT:

final case class User(id: Int, name: String)

An abstract representation of this schema can be retrieved by requesting an instance of the Reified type class.

import dev.tauri.seals.Reified
Reified[User]

This abstract representation is used to implement the following features. (End users usually don't have to work with Reified directly.)

Compile-time compatibility checking

In the next version of the schema defined above, you may want to add a new field (with a default value):

final case class UserV2(id: Int, name: String, age: Int = 42)

Thanks to the default value, these two versions are compatible with each other. We can assert this by using the Compat type class:

import dev.tauri.seals.Compat
Compat[User, UserV2]

If they wouldn't be compatible, we would get a compile time error (because there would be no Compat instance available). For example, if we define a new schema like this:

final case class UserV3(id: Int, name: String, age: Int) // no default `age`

Then there will be no Compat instance available, since the schemata are not compatible:

Compat[User, UserV3] // error: could not find implicit value for ...

For a more detailed introduction to the Compat type class, see this example.

Build-time compatibility checking

By using the seals-plugin module (which is an sbt plugin), we can check in our build whether our current schemata are compatible with previously released versions. (Similarly to how MiMa checks binary compatibility with previous versions.) For how to do this, see this example. The plugin is available for sbt 1.x.

Other features

If you are interested in other features (like automatic derivation of serializers, or runtime compatibility checking), at the moment the best way is to look at the examples or directly at the sources (and Scaladoc comments, and laws/tests).

Project structure

The subprojects are as follows:

Dependencies

seals depends on the following projects:

Currently there are interop modules for the following projects:

For testing, it also uses:

License

seals is open source software under the Apache License v2.0. For details, see the LICENSE.txt, NOTICE.txt, and AUTHORS files.