Skip to content

Instantly share code, notes, and snippets.

@stsatlantis
Last active June 2, 2021 07:41
Show Gist options
  • Save stsatlantis/189a6159f9fd041237ee9b0f0a092538 to your computer and use it in GitHub Desktop.
Save stsatlantis/189a6159f9fd041237ee9b0f0a092538 to your computer and use it in GitHub Desktop.
Optics at Nicecactus
{
"user":"szeretemacsokit",
"sessionId":"8416525d747a48efa744f0c3ce753d76",
"game":{
"id":5426,
"name": "League of Legends"
},
"event":{
"name":"assist",
"data":{
"count":"8"
}
},
"date":"2020-06-02T10:25:00.126Z"
}
{
"user":"szeretemacsokit",
"sessionId":"8416525d747a48efa744f0c3ce753d76",
"game":{
"id":5426,
"name": "League of Legends"
},
"event":{
"name":"death",
"data":{
"count":"8"
}
},
"date":"2020-06-02T10:25:00.126Z"
}
{
"user":"szeretemacsokit",
"sessionId":"8416525d747a48efa744f0c3ce753d76",
"game":{
"id":5426,
"name": ""
},
"event":{
"name":"death",
"data":{
"count":"8"
}
},
"date":"2020-06-02T10:25:00.126Z"
}
import cats.syntax.option._
import java.time.Instant
Envelope(
userId = "szeretemacsokit",
sessionId = "8416525d747a48efa744f0c3ce753d76",
game =
Game(
id = 5426,
name = "".some
)
event =
OverwolfEvent.Event(
name = "death",
data = OverwolfEvent.Event.EventPayload.Death(count = 8)
)
date = ???
)
)
final case class Envelope(
userId: String,
sessionId: String,
date: Instant,
game: Game,
event: OverwolfEvent
)
final case class Game(
id: Int,
name: Option[String]
)
sealed trait OverwolfEvent
object OverwolfEvent {
final case class Event(
name: String,
data: EventPayload
) extends OverwolfEvent
object Event {
sealed trait EventPayload
object EventPayload {
final case class Death(count: Int) extends EventPayload
final case class Assist(count: Int) extends EventPayload
}
}
final case class InfoUpdate(
feature: String,
info: InfoPayload
) extends OverwolfEvent
object InfoUpdate {
sealed trait InfoUpdatePayload
object InfoUpdatePayload {
sealed trait Kill extends InfoUpdatePayload
object Kill {
final case class Kills(kills: Int) extends Kill
final case class Assists(assists: Int) extends Kill
final case class Headshots(headshots: Int) extends Kill
}
}
}
}
{
"user": "szeretemacsokit",
"sessionId": "038565cf00664aecbbcc28ed1bc03abd",
"game": {
"id": 21640,
"name": "Valorant"
},
"event": {
"info": {
"kill": {
"assists": 1
}
},
"feature": "kill"
},
"date": "2020-08-21T22:04:13.158Z"
}
{
"user": "szeretemacsokit",
"sessionId": "038565cf00664aecbbcc28ed1bc03abd",
"game": {
"id": 21640,
"name": "Valorant"
},
"event": {
"info": {
"kill": {
"headshots": 1
}
},
"feature": "kill"
},
"date": "2020-08-21T22:04:13.158Z"
}
{
"user": "szeretemacsokit",
"sessionId": "038565cf00664aecbbcc28ed1bc03abd",
"game": {
"id": 21640,
"name": "Valorant"
},
"event": {
"info": {
"kill": {
"kills": 1
}
},
"feature": "kill"
},
"date": "2020-08-21T22:04:13.158Z"
}
final case class Lens[A, B](
get: A => B,
set: (A, B) => A
) { self =>
def compose[C](other: Lens[B, C]) =
Lens(
get = self.get andThen other.get,
set = (a, c) => self.set(a, other.set(self.get(a), c))
)
def modify(f : B => B): A => A =
a => self.set(a, (self.get andThen f)(a)
}
// original
val removeEmptyGameName : Envelope => Envelope =
message => message.copy(
game = message.game.copy(
name = message.game.name.filter(_.nonEmpty)
)
)
// with Lenses
val envelopeGameLens =
Lens(
get = _.game,
set = (envelope, nemGame) => envelope.copy(game = nemGame)
)
val gameNameLens =
Lens(
get = _.name,
set = (game, newName) => game.copy(name = newName)
)
val removeEmptyGameName : Envelope => Envelope =
(envelopeGameLens compose gameNameLens).modify(_.filter(_.nonEmpty))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment