GithubHelp home page GithubHelp logo

gawkermedia / macrame Goto Github PK

View Code? Open in Web Editor NEW

This project forked from claireneveu/macrame

0.0 10.0 0.0 252 KB

Macrame provides macro-based replacements for parts of the Scala standard library.

License: BSD 3-Clause "New" or "Revised" License

Shell 1.17% Scala 98.83%

macrame's Introduction

Macramé

Macrame provides macro-based replacements for parts of the Scala standard library.

Getting Macramé

This library requires Scala 2.13 and Java 17+. If you're using SBT, add the following to your build file.

libraryDependencies += "com.kinja" %% "macrame" % "2.0.0"
scalacOptions += "-Ymacro-annotations"

Enumerations

Macramé provides an @enum macro annotation to replace Scala's Enumeration class. Unlike Enumeration, @enum classes are fully type-safe and provide exhaustiveness checks. @enum provides a much larger interface than Enumeration but it allows the user to select which functions to expose.

Getting Started

To understand how to use the @enum macro, we'll look at a simple Color enumeration and see what it expands to.

@enum class Color {
   Red
   Blue
   Yellow
}
// Expands to:
sealed abstract class Color extends Product with Serializable
object Color extends EnumApi[Color] {
   case object Red extends Color
   case object Blue extends Color
   case object Yellow extends Color
   <EnumApi implementation elided>
}

Using EnumApi

In order to reduce boilerplate, the @enum macro defines a number of convenient functions on your enumeration type. Auto-generated functions are great but they often increase your API in undesired ways, exposing conversions to/from String that would be better hidden inside more principled conversions.

To resolve this tension, @enum provides the implementations for automatically generated functions as protected members of the companion object, leaving you to expose these functions or use them to implement other functions as you wish. These functions can be found in EnumApi (select "Visibility: All").

@enum class Color {
   Red
   Blue
   Yellow
}
object Color {
   def asString(color : Color) = asStringImpl(color)
   // Replicating Enumeration's partial String->Enumeration.Value conversion.
   def withName(s : String) = fromStringImpl(s)
      .getOrElse(throw new NoSuchElementException(s"No value found for '$s'"))
}

Macramé also provides a number of traits that expose the most commonly used functionality. The Macramé-Play library leverages this approach to provide integration with Play Framework.

@enum class Color {
   Red
   Blue
   Yellow
}
object Color extends enums.StringConverters[Color]
// Allows the following:
// Color.fromString("Red") === Some(Color.Red)
// Color.Yellow.asString === "Yellow"
// Color.asString(Color.Yellow) === "Yellow"

Providing Custom String Representations

As with Enumeration, you can provide custom String representations of your enum cases. These can be either a string literal or an identifier pointing to a string. You can mix-and-match the automatically generated representations with manual ones.

@enum class Color {
   Red("RED")
   Blue("BLUE")
   Yellow("YELLOW")
}
object Color {
   def asString(color : Color) = asStringImpl(color)
   def fromString(s : String) = fromStringImpl(s)
}

Selecting Members

Often the key to good boilerplate-elimination, Macramé provides two functions to select members of objects: members and memberMap. When used inside the selected object, be sure to use type ascriptions otherwise these functions will try to contain themselves.

@enum class Color {
   Red
   Blue
   Yellow
}
object Color {
   val values : List[Color] = members[Color](this)
}

Debugging

The trace macro can be very useful when figuring out why a macro won't work. It outputs to the console during compiliation. The format looks like this:

[info] /home/claire/Programming/scala/macrame/README.scala:70: trace output
[info]    immutable.this.List.apply[Color](this.Red, this.Blue, this.Yellow)
[info] for position:
[info]       val values : List[Color] = trace(members[Color](this))
[info]                                        ^

macrame's People

Contributors

claireneveu avatar balagez avatar ppopoff avatar kalmiz avatar nikodemkler avatar nehaev avatar

Watchers

Patrick avatar Chris Sprehe avatar James Cloos avatar  avatar Péter Szász avatar  avatar Jennifer Bruno avatar  avatar  avatar Lukasz 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.