Git Product home page Git Product logo

derevo's People

Contributors

catostrophe avatar danslapman avatar dependabot[bot] avatar eugkhp avatar funfunfine avatar gvolpe avatar little-inferno avatar lmnet avatar mergify[bot] avatar nkgm avatar odomontois avatar optician avatar ppressives avatar psisoyev avatar rednblack avatar reireirei avatar road21 avatar scala-steward avatar smiklos avatar ssstlis avatar sugakandrey avatar ulanzetz avatar zawodskoj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

derevo's Issues

supertagged integration

It would be cool to have integration with the supertagged library, like with the newtype library.

At the current moment I'm doing something like this in my codebase:

trait encoder {
  type Raw
  type Tag <: this.type

  implicit def liftedEncoder(implicit raw: Encoder[Raw]): Encoder[Raw @@ Tag] = LiftF[Encoder].lift
}

object Example extends TaggedType[String] with encoder
type Example = Example.Type

But I want to write something like this:

@derive(encoder)
object Example extends TaggedType[String] with encoder
type Example = Example.Type

To determine that the type is a TaggedType it's sufficient to check that its companion extends supertagged.TaggedType0[T].

[Question] Json encoded doesn't have bottom level fields names

Screenshot 2021-05-24 at 23 38 30

This is the unit test shown above.

This is where MetaData case classes are.

This is MetaDataClient. This works fine. It's just the unit test doesn't pass.

This is the dependency list.

I am working on Weaver unit tests. My json doesn't have the bottom level field names. There are no frameRate, resolution, md5, sha1 and productionId etc in json string 2. Any suggestions?

Add µPickle support

Would be nice to see support for µPickle which looks like the following:

For case clasess:

import upickle.default.{ReadWriter => RW, macroRW}
case class Thing(myFieldA: Int, myFieldB: String)
object Thing{
  implicit val rw: RW[Thing] = macroRW
}
case class Big(i: Int, b: Boolean, str: String, c: Char, t: Thing)
object Big{
  implicit val rw: RW[Big] = macroRW
}

And for sealed traits:

sealed trait IntOrTuple
object IntOrTuple{
  implicit val rw: RW[IntOrTuple] = RW.merge(IntThing.rw, TupleThing.rw)
}
case class IntThing(i: Int) extends IntOrTuple
object IntThing{
  implicit val rw: RW[IntThing] = macroRW
}
case class TupleThing(name: String, t: (Int, Int)) extends IntOrTuple
object TupleThing{
  implicit val rw: RW[TupleThing] = macroRW
}

Derive [higher-kind] type-classes for DSLs with multiple type parameters

Currently, derevo fails to derive, e.g. functorK, for traits, which are not in the form trait Foo[F[_]]{...}
Additional type parameters make it fail, for example, the following snippet:

@derive(functorK)
trait FooCache[F[_], K, V] {
  def get(key: K): F[Option[V]]
  def upsert(key: K, value: V): F[Unit]
  def invalidate(key: K): F[Unit]
}

will result in

wrong number of type arguments for org.package.FooCache, should be 3

Add support for multiple-type derivation aliases

It would be good to have an ability to alias mutliple derivations at once, so instead of etc

import com.sksamuel.avro4s.{Encoder, Decoder, SchemaFor}

@derive(Encoder, Decoder, SchemaFor)
case class FooBar(foo: String, bar: Int)

one can write (preferred)

@avro4sCodec
case class FooBar(foo: String, bar: Int)

or

@derive(avro4sCodec)
case class FooBar(foo: String, bar: Int)

Fail to derive instances for case class containing newtype fields

Started migrating the shopping-cart application and bumped into this issue

[error] brand.scala:35:4: Could not find io.circe.Decoder instance for shop.domain.brand.BrandId
[error]   @derive(decoder, encoder)
[error]    ^

Given by the following simplified example.

import java.util.UUID

import derevo.derive
import derevo.circe.{ decoder, encoder }
import io.estatico.newtype.macros.newtype

object brand {
  @newtype @derive(decoder, encoder)
  case class BrandId(value: UUID)
 
  @newtype @derive(decoder, encoder)
  case class BrandName(value: String) {
    def toBrand(brandId: BrandId): Brand =
      Brand(brandId, this)
  }
 
  @derive(decoder, encoder)
  case class Brand(uuid: BrandId, name: BrandName)
}

On the other hand, this works without issues:

object brand {
  @newtype case class BrandId(value: UUID)
  object BrandId {
    implicit val jsonEncoder: Encoder[BrandId] = deriving
    implicit val jsonDecoder: Decoder[BrandId] = deriving
  }
 
  @newtype case class BrandName(value: String) {
    def toBrand(brandId: BrandId): Brand =
      Brand(brandId, this)
  }
  object BrandName {
    implicit val jsonEncoder: Encoder[BrandName] = deriving
    implicit val jsonDecoder: Decoder[BrandName] = deriving
  }
 
  @derive(decoder, encoder)
  case class Brand(uuid: BrandId, name: BrandName)
}

Derive and newtype annotations compile error

Usage of both derive and newtype annotations with unnapply parameter for newtype annotation

import io.estatico.newtype.macros.newtype
import derevo.derive
import derevo.circe.magnolia.encoder

object Main extends App {

  object Foo {

    @derive(encoder)
    @newtype(unapply = true)
    final case class Bar(val str: String)

  }

}

leads to compilation error

Publish for Scala.js

I have a local build going.
Can do PR if it's something you would consider merging.

Macro annotation expansion of @derive doesn't work having local imports of derevo.cats._

The following code doesn't compile on scala 2.13.5 (local import of derevo.cats._):

import cats.Monoid

object AnnotationProblem {
  import derevo.derive
  import derevo.cats.{eqv, monoid, order, show}

  @derive(eqv, show, order, monoid)
  case class ABC(
    a: String,
    b: Int,
    c: Boolean
  )

  val abcEmpty = Monoid[ABC].empty
}

Compilation error:

exception during macro expansion: 
scala.reflect.macros.TypecheckException: not found: value eqv
	at scala.reflect.macros.contexts.Typers.$anonfun$typecheck$3(Typers.scala:44)
...

https://scastie.scala-lang.org/mbelikov/RARK4uYyRsuV3tEtvnOhIQ/4

Putting the import of derevo.cats._ to the global scope solves the compilation problem:
https://scastie.scala-lang.org/mbelikov/RARK4uYyRsuV3tEtvnOhIQ/6

The issue seems to be scala 2.13.x specific, for the 2.12 compiler the local import is ok:
https://scastie.scala-lang.org/mbelikov/RARK4uYyRsuV3tEtvnOhIQ/7

Add support for typesafe circe configurations

Currently the only way to specify a way to encode/decode values for derevo-circe's encoder/decoder is by passing fully qualified name as a string to macroannotation. It would be nice to support a more typesafe way of doing so, i.e. @derive(encoder(snakeCaseMemberNames))

Circe's KeyDecoder and KeyEncoder derivations?

AFAIU the derivations supported by derevo are the ones supported by circe-derivation, is that right? If so, then I guess it is not possible to derive KeyDecoder and KeyEncoder instances without upstream support?

Anyhow, my only need for now is to support derivation for these typeclasses for newtypes. Here's a simple example:

@derive(decoder, encoder, eqv, show, uuid)
@newtype
case class ItemId(value: UUID)
object ItemId {
  implicit val keyEncoder: KeyEncoder[ItemId] = deriving
  implicit val keyDecoder: KeyDecoder[ItemId] = deriving
}

There are KeyDecoder[UUID] and KeyEncoder[UUID] instances so this works but I wanted to go a bit further and get Derevo to do this for me. This is what I come up with.

import derevo.{ Derivation, NewTypeDerivation }
import io.circe.KeyDecoder
import magnolia.{ CaseClass, Magnolia }

object keyDecoder extends Derivation[KeyDecoder] with NewTypeDerivation[KeyDecoder] {
  type Typeclass[T] = KeyDecoder[T]

  def combine[T](ctx: CaseClass[KeyDecoder, T]): KeyDecoder[T] = new KeyDecoder[T] {
    def apply(key: String): Option[T] =
      ctx.parameters.toList match {
        case (p :: _) => p.typeclass.apply(key).map(_.asInstanceOf[T])
        case _        => None
      }
  }

  def instance[T]: KeyDecoder[T] = macro Magnolia.gen[T]
}

Do you see anything wrong?

I did something similiar for KeyEncoder but this one is weird because I need to return a String and not sure what the empty case should be.

object keyEncoder extends Derivation[KeyEncoder] with NewTypeDerivation[KeyEncoder] {
  type Typeclass[T] = KeyEncoder[T]

  def combine[T](ctx: CaseClass[KeyEncoder, T]): KeyEncoder[T] = new KeyEncoder[T] {
    def apply(key: T): String =
      ctx.parameters.toList match {
        case (p :: _) => p.typeclass.apply(key.asInstanceOf[p.PType])
        case _        => "error"
      }
  }

  def instance[T]: KeyEncoder[T] = macro Magnolia.gen[T]
}

This works but I wonder if there is any downside or something wrong in my implementations?

@derive(decoder, encoder, keyDecoder, keyEncoder, eqv, show, uuid)
@newtype
case class ItemId(value: UUID)

Appreciate your help, I've never used Magnolia before.

Macro expansion fails if the companion has annotations

Compiling this:

@derive(functor)
trait Bar[A] {
  def bar(x: Int): A
}

@SuppressWarnings(Array("deprecation")) // any annotation here
object Bar

leads to exception:

macro expansion has failed: scala.MatchError: List(abstract trait Bar[A] extends scala.AnyRef {
[error] /home/***.scala:4:2: exception during macro expansion: 
[error] scala.MatchError: List(abstract trait Bar[A] extends scala.AnyRef {
[error]   def bar(x: Int): A
[error] }, @new SuppressWarnings(Array("deprecation")) object Bar extends scala.AnyRef {
[error]   def <init>() = {
[error]     super.<init>();
[error]     ()
[error]   }
[error] }) (of class scala.collection.immutable.$colon$colon)
[error] 	at org.manatki.derevo.Derevo.deriveMacro(Derevo.scala:55)
[error] @derive(functor)
[error]  ^
[error] one error found

Compile intellij integration with Scala 2.13 for IDEA 2020.3

Since 2020.3 Scala plugin for IntelliJ IDEA will use Scala 2.13. New version of library extension compiled with Scala 2.13 should be published.

java.lang.NoSuchMethodError: 'scala.collection.mutable.WrappedArray scala.Predef$.wrapRefArray(java.lang.Object[])'
	at derevo.intellij.DerevoDeriveInjector$.<init>(DerevoDeriveInjector.scala:87)
	at derevo.intellij.DerevoDeriveInjector$.<clinit>(DerevoDeriveInjector.scala)
	at derevo.intellij.DerevoDeriveInjector.needsCompanionObject(DerevoDeriveInjector.scala:12)
	at org.jetbrains.plugins.scala.lang.psi.impl.toplevel.typedef.SyntheticMembersInjector$.$anonfun$needsCompanion$1(SyntheticMembersInjector.scala:146)
	at org.jetbrains.plugins.scala.lang.psi.impl.toplevel.typedef.SyntheticMembersInjector$.$anonfun$needsCompanion$1$adapted(SyntheticMembersInjector.scala:146)
	at scala.collection.ArrayOps$.exists$extension(ArrayOps.scala:684)
	at org.jetbrains.plugins.scala.lang.psi.impl.toplevel.typedef.SyntheticMembersInjector$.needsCompanion(SyntheticMembersInjector.scala:146)
...

Hocon collections decoded in reverse order

data {
  name = Demo
  list = [1, 2, 3]
  map.wtf = 1
  map.lol = 2
  map.wut = 3
  rate {
    elements = 2
    duration = 100 millis
  }
}

The above hocon sample from CirisSpec.scala yields:

Data(Demo,List(3, 2, 1),Map(wut -> 3, lol -> 2, wtf -> 1),Rate(2))

Add support for the Newtype library

It seems the @newtype annotation from the scala-newtype library doesn't work well with the @derive annotation.

This fails to compile:

@newtype
@derive(show)
case class Foo(value: String)

@newtype
@derive(show)
case class Bar(value: Int)

@derive(show)
final case class Ctx(foo: Foo, bar: Bar)

Here's the error:

[error] /examples/foo.scala:19:4: magnolia: could not find Show.Typeclass for type examples..Foo
[error]     in parameter 'foo' of product type examples.Ctx
[error]   @derive(show)
[error]    ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed

Maybe worth looking into scalaz-deriving that has support for it.

Rename derevo.cats.eq to derevo.cats.eqv?

Apologies if this was discussed before but I was wondering if you have considered renaming this? Even the examples in the README file show a qualified import derevo.cats.{ eq => eqv } since trying to use @derive(eq) yields the error missing argument list for method eq in class Object.

I'd be happy to submit a PR if so :)

Derive and newtype annotations implicit error

import derevo.cats.{eqv, show}
import derevo.circe.magnolia.{decoder, encoder}
import derevo.derive
import io.estatico.newtype.macros.newtype
import io.circe.refined._
import org.mongodb.scala.bson.annotations.BsonProperty
import eu.timepit.refined.cats._
import derevo.reactivemongo.{bsonDocumentReader, bsonDocumentWriter}

object myObject {

  @derive(decoder, encoder, eqv, show, bsonDocumentReader, bsonDocumentWriter)
  @newtype case class Id(value: String)
  
   @derive(decoder, encoder, eqv, show)
   @newtype case class Name(value: String)
  
  @derive(decoder, encoder, eqv, show)
  case class MyOject(@BsonProperty("_id") id: Id, name: Option[Name])
}

could not find implicit value for parameter repr: reactivemongo.bson.BSONDocumentReader[String]
@derive(decoder, encoder, eqv, show, bsonDocumentReader, bsonDocumentWriter)

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.