GithubHelp home page GithubHelp logo

isabella232 / scrooge-shapes Goto Github PK

View Code? Open in Web Editor NEW

This project forked from stripe-archive/scrooge-shapes

0.0 0.0 0.0 17 KB

Shapeless generic instances for Scrooge types

License: Apache License 2.0

Scala 98.17% Thrift 1.83%

scrooge-shapes's Introduction

Scrooge Shapes

Build status Coverage status Maven Central

This project provides instances of Shapeless's Generic type classes for types generated for Apache Thrift definitions by Twitter's Scrooge.

These instances allow you to use the generic derivation mechanisms provided by libraries like Circe or scalacheck-shapeless to generate boilerplate-free type class instances for your Scrooge types.

Note that this library does not bring its own runtime dependency on either Scrooge or libthrift, and the macros provided here have been used on a range of Scrooge versions, from 4.6.0 to 18.2.0. Currently only a single (recent) Scrooge version is being tested and supported, but this may change in the future.

History

This library is based on a demonstration project written by Travis Brown in 2016, and is now used internally at Stripe to support generic derivation and other applications.

Usage

Given a Thrift definition like the following, Scrooge will generate a Scala type that is case class-like, but not a case class:

namespace java com.stripe.scrooge.shapes

struct MapExample {
  1: required string id
  3: optional map<string,string> metadata
}

Shapeless cannot derive Generic or LabelledGeneric instances for types like this on its own, which is where Shapes comes in—you simply import the contents of the package object and then you can use any generic derivation mechanism as if you were working with ordinary case classes or sealed trait hierarchies.

scala> import com.stripe.scrooge.shapes._
import com.stripe.scrooge.shapes._

scala> import io.circe.ObjectEncoder, io.circe.syntax._
import io.circe.ObjectEncoder
import io.circe.syntax._

scala> import io.circe.generic.semiauto.deriveEncoder
import io.circe.generic.semiauto.deriveEncoder

scala> implicit val encodeMapExample: ObjectEncoder[MapExample] = deriveEncoder
encodeMapExample: io.circe.ObjectEncoder[com.stripe.scrooge.shapes.MapExample] = io.circe.generic.encoding.DerivedObjectEncoder$$anon$1@2ecb4528

scala> MapExample("abc", Some(Map("foo" -> "bar", "baz" -> "quz"))).asJson
res0: io.circe.Json =
{
  "id" : "abc",
  "metadata" : {
    "foo" : "bar",
    "baz" : "quz"
  }
}

See the GenericInstancesTest test suite for more details about the representations used for these types. In particular note that if you're working with a Thrift union, you may need to provide instances of your target type class for TFieldBlob explicitly. For example, if you want to want to use Circe's generic derivation with a union like this:

namespace java com.stripe.scrooge.shapes

struct StructExample {
  1: required string foo
  2: optional string bar
}

union UnionExample {
  1: StructExample a
  2: i32 b
  3: string c
}

You will need some utility code like the following:

import io.circe.Encoder, io.circe.scodec._, io.circe.syntax._
import com.twitter.scrooge.TFieldBlob, scodec.bits.ByteVector

implicit val encodeTFieldBlob: Encoder[TFieldBlob] =
  Encoder.instance(blob => ByteVector(blob.data).asJson)

This will allow you to derive Encoder and Decoder types for UnionExample:

import com.stripe.scrooge.shapes._, io.circe.generic.auto._

scala> val ex: UnionExample = UnionExample.A(StructExample("abc", Some("123")))
ex: com.stripe.scrooge.shapes.UnionExample = A(StructExample(abc,Some(123)))

scala> ex.asJson
res0: io.circe.Json =
{
  "A" : {
    "foo" : "abc",
    "bar" : "123"
  }
}

Without the TFieldBlob encoder, Circe would not know how to encode the UnknownUnionField disjunct that is included in Scrooge's representation of every union, and its generic derivation would fail to compile.

License

scrooge-shapes 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.

scrooge-shapes's People

Contributors

travisbrown avatar travisbrown-stripe avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.