• Stars
    star
    56
  • Rank 530,104 (Top 11 %)
  • Language
    Scala
  • Created over 7 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Generate bindings for Scala types in other programming languages.

Bridges

Generate bindings for Scala types in other programming languages.

Copyright 2017-2019 Dave Gurnell. Licensed Apache 2.0.

Maintainers:

  • Dave Gurnell (Flow and Typescript support)
  • Pere Villega (Elm support)

Build Status Coverage status Maven Central

Getting Started

Grab the code by adding the following to your build.sbt:

libraryDependencies += "com.davegurnell" %% "bridges" % "<<VERSION>>"

Synopsis

Render Typescript/Flow Declarations for Scala ADTs

First, create a simple data model:

final case class Color(red: Int, green: Int, blue: Int)

sealed abstract class Shape extends Product with Serializable
final case class Circle(radius: Double, color: Color) extends Shape
final case class Rectangle(width: Double, height: Double, color: Color) extends Shape

The bridges.typescript and bridges.flow packages expose similar APIs for encoding ADTs as structural types.

The decl[Foo] method creates an object representing a type declaration for Foo.

The render(...) method writes a list of declaration objects to a String in the relevant target language. Here's an example for Typescript:

import bridges.typescript._
import bridges.typescript.syntax._

Typescript.render(List(
  decl[Color],
  decl[Circle],
  decl[Rectangle],
  decl[Shape]
))
// res1: String =
// export interface Color {
//   red: number;
//   green: number;
//   blue: number;
// };
//
// export interface Circle {
//   radius: number;
//   color: Colo;
// };
//
// export interface Rectangle {
//   width: number;
//   height: number;
//   color: Color;
// };
//
// export type Shape =
//   {
//     type: "Circle",
//     radius: number,
//     color: Color
//   } |
//   {
//     type: "Rectangle",
//     width: number,
//     height: number,
//     color: Color
//   };

Simply replace the imports to target Flow instead:

import bridges.flow._
import bridges.flow.syntax._

Flow.render(List(
  decl[Color],
  decl[Circle],
  decl[Rectangle],
  decl[Shape]
))

The syntax packages also provide a simple DSL for defining structural types directly:

import bridges.typescript._
import bridges.typescript.TsType._
import bridges.typescript.syntax._

val logMessage: TsDecl =
  decl("LogMessage")(struct(
    "level" --> union(lit("error"), lit("warning")),
    text    --> Str
  )

Typescript.render(logMessage)
// res0: String =
// export interface LogMessage {
//   level: "error" | "warning";
//   text: string;
// };

You can even create generic types using the DSL, which is something the shapeless derivation currently can't handle:

import bridges.typescript._
import bridges.typescript.TsType._
import bridges.typescript.syntax._

val pair: TsDecl =
  decl("Pair", "A", "B")(struct(
    "head" --> Ref("A"),
    "tail" --> Ref("B"),
  )

Typescript.render(pair)
// res0: String =
// export interface Pair<A, B> {
//   head: A;
//   tail: B;
// };

Render Elm Definitions and JSON Codecs for Scala ADTs

The bridges.elm package generates type definitions and JSON codecs for Elm:

  • Elm.render generates a type definition for a list of declarations;
  • Elm.jsonDecoder generates an Elm Decode.Decoder
  • Elm.jsonEncoder generates an Elm Encoder
  • Elm.buildFile returns a pair (String, String) where the first element is the name of an Elm file and the second element is the content for that file, containing type and JSON codec definitions.

To avoid circular references, Elm.buildFile can generate a single file for a list of declarations.

If you want to use any of the JSON encoders or decoders generated by the project you need to do the following:

  • Your Elm project must include the NoRedInk/elm-decode-pipeline dependency
  • We assume any non-primitive type in your ADT will be generated by Bridges in the same module as the current ADT, to be able to define the right imports for them.
  • If your ADT contains a sum type, the generated json must distinguish between alternatives using a field named type that encodes the name of the product instance as a String. If you use Circe, see this link.

NOTE: automatic encoder and decoder generation doesn't work for types with Generics. You will need to manually create your own.

Working with Refined types

If you are interested in this library you are most likely using Refined.

We have provided a default encoder for refined types. It will defaults to the basic type associated with the refined type. For example:

  • For Int Refined Greater[W.6.T] we treat the type as an Int
  • For String Refined Size[ClosedOpen[W.1.T, W.100.T]] we treat the type as a String
  • etc

This should cover most (if not all) use cases of refined types when converting to other languages. You can still override the default encoder with your own higher-precedence encoder.

You can see an example of this in tests for class ClassWithRefinedType.

Developing

  • Development should be completed on feature branches and submitted by PR to master.
  • Commits to master are published as snapshot builds.
  • Tags of the form x.y.z are published as release builds.

More Repositories

1

unindent

Indent-adjusted multiline string literals for Scala.
Shell
48
star
2

checklist

Validation library for Scala.
Scala
47
star
3

bulletin

Automatically perform shallow merges on case classes. Treat your data with the latest updates!
Scala
42
star
4

meowsynth

The mighty meowing synthesizer!
Scala
30
star
5

validation

Scala data validation library
Scala
29
star
6

typelevel-todomvc

Scala
25
star
7

atlas

A tiny embedded scripting language implemented in Scala.
Scala
24
star
8

shapeless-guide

The Type Astronaut's Guide to Shapeless
19
star
9

functional-data-validation

Slides and code samples for a talk on thinking functionally (and validating web forms).
Scala
18
star
10

99-ways-to-di

Slides from my lightning talk on Dependency Injection at Scala Central #5.
14
star
11

css-selector

Lift-style CSS selector transforms based on Scalate's Scuery
Scala
10
star
12

tipi

Tiny templating language written in Scala.
Scala
10
star
13

macros-vs-shapeless

Slides and code samples on meta-programming techniques in Scala.
Scala
10
star
14

spandoc

Write Pandoc filters in Scala.
Scala
7
star
15

scalalol-2011-talk

Slides and code samples for talk at Scala Lift-Off London 2011.
Scala
6
star
16

scala-opengl

Simple OpenGL examples using Scala, LWJGL, and sbt-lwjgl
Scala
6
star
17

shapeless-guide-slides

Slides for my Scala World 2016 workshop on shapeless.
6
star
18

smartypants

Simple smart constructor generation for Scala.
Scala
4
star
19

scalax2gether-2017

Workshop and hack proposals for the Scala Exchange Hack Day (ScalaX2gether 2017)
4
star
20

shapeless-sandbox

Scala
3
star
21

scalax-2014

Slides and code samples for my Scala Exchange 2014 talk on Functional Data Validation.
3
star
22

typelevel-philly-2016

3
star
23

sbt-less

Superseded by sbt-less in https://github.com/untyped/sbt-plugins.
Scala
3
star
24

akka-streams-case-study

Scala
2
star
25

poker-case-study

Poker hand comparison in Scala. A fairly advanced "Essential Scala" case study.
Scala
2
star
26

interpreter-case-study

Scala case study about building an interpreter and a simple DSL.
Scala
2
star
27

cats-error-case-study

Scala
2
star
28

bus-driver-case-study

Gossiping Bus Drivers Kata
Scala
2
star
29

scala-rpg-test

A sandbox project for playing with Scala and the graphics from Browserquest.
Scala
2
star
30

concurrency-case-study

Scala
2
star
31

versionit

Grab your Git commit hash as a Scala String.
Scala
2
star
32

advanced-scala-scalax15

Code written at Advanced Scala at Scala Exchange 2015
Scala
1
star
33

spectaskular-iphone

iPhone todo list app
Objective-C
1
star
34

brighton-java-sample-app

Scala talk for Brighton Java
CSS
1
star
35

session-cell

Cookie-based in-memory session storage for the Racket HTTP Server.
Scheme
1
star
36

kitties-case-study

Meow!
Scala
1
star
37

gilded-rose-case-study

Code refactoring kata
Scala
1
star
38

conway-case-study

Scala
1
star
39

mars-rover-case-study

Scala
1
star
40

asyncjs-creative-fp

Creative Functional Programming talk for AsyncJS.
1
star
41

parallel-case-study

Scala
1
star
42

bank-ocr-case-study

Scala
1
star
43

play-json-case-study

Scala
1
star
44

calc-case-study

Scala
1
star
45

bowling-case-study

Scala
1
star
46

advanced-scala

The old source code repository for Scala with Cats
1
star
47

paths-case-study

Essential Scala case study: selecting paths from a route finder service
Scala
1
star
48

typeclub

Scala
1
star
49

tagless-case-study

Scala
1
star
50

composejs

Javascript port of Compose (https://github.com/underscoreio/compose).
JavaScript
1
star
51

doodlejs

Javascript port of Doodle
JavaScript
1
star
52

fpinscala

My attempts at the exercises in Functional Programming in Scala.
Scala
1
star
53

shapeless-guide-code

The Type Astronaut's Guide to Shapeless (Example Code)
1
star
54

scaladays-berlin-2016

1
star
55

property-based-testing-workshop

Scala
1
star
56

advanced-scala-exercises

Scala
1
star
57

away-with-the-types

Scala
1
star
58

cats-effect-sandbox

An empty SBT project with dependencies on Cats and Cats Effect.
Scala
1
star