Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jan 26 2019 21:07
    scala-steward synchronize #139
  • Jan 26 2019 14:33

    mpilquist on v1.11.0

    (compare)

  • Jan 26 2019 14:32

    mpilquist on 1.11.x

    Setting version to 1.11.0 Updated version to 1.11.1-SNAPS… (compare)

  • Jan 25 2019 10:28
    billpcs starred scodec/scodec
  • Jan 22 2019 22:01
    benhanna starred scodec/scodec
  • Jan 21 2019 20:36
    scala-steward opened #139
  • Jan 21 2019 14:51
    mpilquist closed #130
  • Jan 21 2019 14:48
    mpilquist closed #119
  • Jan 21 2019 14:48
    mpilquist commented #119
  • Jan 21 2019 14:48

    mpilquist on 1.11.x

    Scala 2.13.0-M4 Merge branch 'series/1.10.x' in… Upgraded to latest scala-collec… and 2 more (compare)

  • Jan 21 2019 14:48
    mpilquist closed #138
  • Jan 21 2019 14:40
    mpilquist opened #138
  • Jan 21 2019 14:37

    mpilquist on 1.11.x

    Created 1.11 branch (compare)

  • Jan 21 2019 14:31

    mpilquist on xuwei-k

    Upgraded to 2.13.0-M5 (compare)

  • Jan 21 2019 14:19

    mpilquist on xuwei-k

    Scala 2.13.0-M4 Merge branch 'series/1.10.x' in… Upgraded to latest scala-collec… (compare)

  • Jan 21 2019 14:03

    mpilquist on 1.10.x

    Update sbt-scalajs, scalajs-com… Merge pull request #129 from sc… (compare)

  • Jan 21 2019 14:03
    mpilquist closed #129
  • Jan 21 2019 14:03
    mpilquist closed #126
  • Jan 21 2019 14:03

    mpilquist on 1.10.x

    Pad-left on pbcd codec. Fixes #… Using padLeft in pbcd instead o… Merge pull request #133 from lJ… (compare)

  • Jan 21 2019 14:03
    mpilquist closed #133
Martijn Hoekstra
@martijnhoekstra
int32 for Int and int64 for Long
Paul Snively
@paul-snively
Right.
So you may want to define your own implicits.
Martijn Hoekstra
@martijnhoekstra
as long as Int are always the same binary representations, that will work within the same scope if I make sure I bring the correct implicits in scope for Int. But that's not always going to be the case
I can tag them maybe to indicate what they are intended to be (de)serialized to/from, but that just feels wrong
Paul Snively
@paul-snively
So you may want to have > 1 module with different implicits.
Or you can compose the Codecs with ~ and xmap to/from the Generic representation of your case class yourself.
There are several ways to skin this cat.
Martijn Hoekstra
@martijnhoekstra
that latter approach sound more promising to me, but I'm not sure how I should do that.
Paul Snively
@paul-snively
Well, to start, how about just:
val codec = uint32 ~ uint32 ~ uint16 ~ uint16 ~ uint32 ~ uint32 ~ uint32 ~ uint32
That is what you want, right?
Martijn Hoekstra
@martijnhoekstra
yes
Paul Snively
@paul-snively
Super. So, what does that give you?
Martijn Hoekstra
@martijnhoekstra
a Codec[(Long, (Long, (Int, (Int, (Long, (Long, (Long, (Long, Long))))))))]
Paul Snively
@paul-snively
Yep. Pain in the neck, huh?
Martijn Hoekstra
@martijnhoekstra
yeah, that's how I started out
Paul Snively
@paul-snively
How about:
val codec = (uint32 ~ uint32 ~ uint16 ~ uint16 ~ uint32 ~ uint32 ~ uint32 ~ uint32).flattenLeftPairs
Paul Snively
@paul-snively
psnively-psnively@ val codec = (uint32 ~ uint32 ~ uint16 ~ uint16 ~ uint32 ~ uint32 ~ uint32 ~ uint32).flattenLeftPairs 
codec: Codec[Long :: Long :: Int :: Int :: Long :: Long :: Long :: Long :: HNil] = scodec.Codec$$anon$2@f7d07809
Much better, right?
Paul Snively
@paul-snively
So we're 90% done.
Now:
val gen = Generic[MpqHeader]
That gives us:
gen: Generic[MpqHeader]{type Repr = Long :: Long :: Int :: Int :: Long :: Long :: Long :: Long :: shapeless.HNil} = ammonite.$sess.cmd5$anon$macro$9$1@f5e8b699
NB: the Repr type =:= the Codec type above.
So:
psnively-psnively@ codec.xmap(gen.from, gen.to) 
res14: Codec[MpqHeader] = scodec.Codec$$anon$2@285208c6
And that's the ballgame.
Martijn Hoekstra
@martijnhoekstra
ah, that makes so much more sense
Paul Snively
@paul-snively
😁
Martijn Hoekstra
@martijnhoekstra
I also discovered you can do it as: val codec = (uint32 :: uint32 :: uint16 :: uint16 :: uint32 :: uint32 :: uint32 :: uint32).as[MpqHeader]
Paul Snively
@paul-snively
Even better. I’ve never used .as.
Paul Snively
@paul-snively
Oh, OK. .as wants an implicit Transformer, and there are all sorts of derived Transformers around Shapeless' Generic.Aux. Got it.
Paul Snively
@paul-snively
@martijnhoekstra: Honestly, the HList of Codecs should have occurred to me in the first place.
Anthony Cerruti
@srnb_gitlab
Any chance I can StreamDecoder#or?
Or at least pick a sub-decoder based on a packet ID
Anthony Cerruti
@srnb_gitlab
Oh, I got it, nevermind
just byte.consume
Anthony Cerruti
@srnb_gitlab
I want to "read ahead" with a decoder without consuming
Anthony Cerruti
@srnb_gitlab
(peek requires Codec)
Anthony Cerruti
@srnb_gitlab
Yeah, my big problem right now is figuring out how to build a codec that's like vector(byte.consume(b => if(b == 0) exitVectorLoop else doStuffWith(b)))
It's really the only problem I'm having
Anthony Cerruti
@srnb_gitlab
I tried writing a
  def consumeUntil[A, B](consume: Codec[A], until: Codec[B]): Codec[(Vector[A], B)] = {
    val rightConsume = consume.xmap[Either[B, A]](_.asRight[B], { case Right(c) => c })
    val leftUntil = until.xmap[Either[B, A]](_.asLeft[A], { case Left(u) => u })
    val go: Codec[(Vector[A], B)] = choice(leftUntil, rightConsume).xmap[(Vector[A], B)]({
      case Left(end) => (Vector.empty, end)
      case Right(continue) =>
        val a: Codec[(Vector[A], B)] = go.xmap[(Vector[A], B)]({
          case (v, t) =>
            (continue +: v, t)
        }, {
          case (v, t) =>
            (v.tail, t)
        })
        ???
    }, {
      case (v, t) =>
        ???
    })
    go
  }
Is there some sort of xflatMap?
Anthony Cerruti
@srnb_gitlab
  def consumeUntil[A, B](consume: Codec[A], until: Codec[B]): Codec[(Vector[A], B)] = {
    val rightConsume = consume.xmap[Either[B, A]](_.asRight[B], { case Right(c) => c })
    val leftUntil = until.xmap[Either[B, A]](_.asLeft[A], { case Left(u) => u })
    val eitherConsumeOrUntil = choice(leftUntil, rightConsume).asDecoder
    def recursiveDec(initial: BitVector, step: Vector[A]): Attempt[DecodeResult[(Vector[A], B)]] = {
      eitherConsumeOrUntil.decode(initial).flatMap {
        case DecodeResult(Left(done), remainder) => Attempt.Successful(DecodeResult((step, done), remainder))
        case DecodeResult(Right(continue), remainder) => recursiveDec(remainder, step :+ continue)
      }
    }
    val goDecode: Decoder[(Vector[A], B)] = Decoder.apply { bitVec =>
      recursiveDec(bitVec, Vector.empty)
    }
    val goEncode: Encoder[(Vector[A], B)] = Encoder.apply { tup =>
      val (v: Vector[A], t: B) = tup
      v.traverse(consume.encode).map(_.combineAll).flatMap(vbv => until.encode(t).map(vbv ++ _))
    }
    Codec(goEncode, goDecode)
  }
Here's my current version