Skip to content

2.0.0 – API improvements and faster parser

Choose a tag to compare

@BrianHicks BrianHicks released this 26 Jan 15:40
· 92 commits to main since this release

This upgrade makes a few tweaks to the API to make creating decoders easier.

API Changes

Pipeline renaming

pipeline is now into, and required is now pipeline. This makes pipeline code nicer:

decoder : Decoder Pet
decoder =
    Decode.into Pet
        |> Decode.pipeline (Decode.field "id" Decode.int)
        |> Decode.pipeline (Decode.field "name" Decode.string)
        |> Decode.pipeline (Decode.field "species" Decode.string)
        |> Decode.pipeline (Decode.field "weight" (Decode.blank Decode.float))

fromResult

fromResult now just takes a Result String a instead of a function that produces a Result String a. This is to make scenarios like this possible:

Decode.string
    |> Decode.map String.toLower
    |> Decode.andThen (Decode.fromResult << Hex.fromString)

This was previously impossible—the design of fromResult made it so that you could not do any pre-processing to your strings before your conversion function got them. You have to do a little more work now, but in exchange you get a lot more flexibility.

API Additions

To make up for breaking your code, I also added fromMaybe : String -> Result String a. It does the same thing as fromResult (fails when it doesn't get a value) but asks you to provide an error message for the failure since Nothing has no info for us to use.

Faster Parser

This release switches to a hand-rolled parser, which is faster than the one released in 1.0.0. It's 25 times faster for "normal" CSVs—that is, those delimited with , or ;. If you use other characters to delimit your fields, it's a little slower but still something like 24 times faster than the 1.0.0 parser. Thank you to @w0rm for advice on squeezing every last bit of performance out of the code.

As a consequence of the upgrade, this package no longer depends on elm/parser. If you added it to your transitive dependencies when you installed this package, you can remove it on upgrade.

Look out for some blog posts from @BrianHicks soon on how he achieved this speedup!

Upgrade Instructions

  • Replace Decode.pipeline with Decode.into, and then Decode.required with Decode.pipeline. If you do it in that order, it should be safe to run a global find/replace on your code!
  • Lift any instances of fromResult: where you previously would have had fromResult Hex.fromString you now will have string |> andThen (fromResult << Hex.fromString).
  • If you were case-matching on any problems in Csv.Parser, you'll have to read the code to figure out what's wrong. Fortunately, it should actually be giving more descriptive error messages now—previously they were just Parser.DeadEnds, now they have meaning specific to CSVs!