Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frees & Avro schema fixes #13

Merged
merged 15 commits into from
Oct 19, 2018
Merged

Frees & Avro schema fixes #13

merged 15 commits into from
Oct 19, 2018

Conversation

pepegar
Copy link
Member

@pepegar pepegar commented Oct 10, 2018

This PR:

  • renames frees/service.scala to frees/protocol.scala to be homogeneous with avro & protobuf
  • deletes droste contrib module that has been already contributed to droste.
  • adds helper methods to avro ADT
  • creates transformer between AvroF & FreesF schemata
  • creates a rendering algebra from AvroF[A] to circe.Json and creates the renderer from avro.Protocol[A] to circe.Json.

@pepegar pepegar changed the title Frees schema fixes Frees & Avro schema fixes Oct 10, 2018
@pepegar pepegar requested a review from a team October 11, 2018 09:08
Copy link

@diesalbla diesalbla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few suggestions.

)): _*)
)
val withNamespace = namespace.fold(base) { n =>
base deepMerge Json.obj("namespace" -> Json.fromString(n))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this particular case, would deepMerge be the same as:

base.mapObject( _.add ("namespace", Json.fromString(n) ) )

"name" -> Json.fromString(name),
"fields" -> Json.arr(
fields.map(
f =>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This 4-line lambda should go to an auxiliary function def fieldToObj?

"type" -> Json.fromString("map"),
"values" -> values
)
case TRecord(name, namespace, aliases, doc, fields) =>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are into a bit of Origami-like programming, you could write this case as follows:

  • From each of namespace, aliases, and doc, compute an Option[( String, Json) ]:
val namespaceOF = namespace.map( n => "namespace" -> Json.fromString(n) _" 
val aliasesOF  = if (aliases.isEmpty) None else Some( "aliases" -> Json.arr(aliases.map(Json.fromString): _*) )
val docOF  = doc.map( f => "doc" -> Json.fromString(f) )
  • Add a function addField(js: Json, of: Option[(String, Json)]), which adds a field to a Json object.
  • Get the result as List(namespaceOF, aliasesOF, docOF).foldLeft(base)(addField)

An alternative, but I would not say if it is cleaner. At your taste.

Copy link

@diesalbla diesalbla Oct 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another alternative is that you start with the list of fields of base, with type, name, fields; and you make namespaceOf or aliasesOf into lists (empty or single), and you concatenate those lists, and apply the Json.obj constructor at the end

build.sbt Outdated
@@ -59,7 +59,8 @@ lazy val commonSettings = Seq(
ThisBuild / scalacOptions -= "-Xplugin-require:macroparadise",
libraryDependencies ++= Seq(
%%("cats-core"),
"io.higherkindness" %% "droste-core" % "0.3.1",
"io.higherkindness" %% "droste-core" % "0.5.0",
"io.higherkindness" %% "droste-macros" % "0.5.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Odd formatting here, we might want to apply the scalafmt syntax also for the sbt files.. makes sense?

case object AvroWithSchema extends SerializationType
}

case class Protocol[T](
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final?

}
}

case class Service[T](name: String, serializationType: SerializationType, operations: List[Service.Operation[T]])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final case class?

"request" -> Json.arr(
Json.obj(
"name" -> Json.fromString("arg"), //TODO: is this doable?
"type" -> scheme.cata(AvroF.toJson).apply(message.request)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend caching/saving scheme.cata(AvroF.toJson) to a val (or lazy val) and then calling it here.

"type" -> scheme.cata(AvroF.toJson).apply(message.request)
)
),
"response" -> scheme.cata(AvroF.toJson).apply(message.response)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

case FreesF.TOption(value) => tUnion(NonEmptyList(tNull[T]().embed, List(value)))
case FreesF.TList(value) => tArray(value)
case FreesF.TMap(value) => tMap(value)
case FreesF.TGeneric(_, _) => ??? // WAT
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the long term, you could do a TransM through Option to account for this failure scenario.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, it's in my plans, but I need to do some changes to droste's traverse derivation, since its a bit far from flawless so far... (I need traverse to be able to use M version of recursion schemes, and I don't want to implement by hand now :))


case class Service[T](name: String, serializationType: SerializationType, operations: List[Service.Operation[T]])
object Service {
case class Operation[T](name: String, request: T, response: T)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final :)

@@ -40,46 +40,49 @@ object FreesF {
case class TOption[A](value: A) extends FreesF[A]
case class TList[A](value: A) extends FreesF[A]
case class TMap[A](value: A) extends FreesF[A]
case class TGeneric[A](generic: A, params: List[A]) extends FreesF[A]
case class TRequired[A](value: A) extends FreesF[A]
case class TCoproduct[A](invariants: NonEmptyList[A]) extends FreesF[A]
case class TSum[A](name: String, fields: List[String]) extends FreesF[A]
case class TProduct[A](name: String, fields: List[Field[A]]) extends FreesF[A]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

even more final :)

@pepegar pepegar merged commit 8e78eb9 into master Oct 19, 2018
@pepegar pepegar deleted the frees-schema-fixes branch October 20, 2018 11:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants