Format code with erlfmt, run dialyzer in CI
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index cfd4c49..1316ffe 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -27,6 +27,7 @@
           persist-credentials: false
           submodules: recursive
       - name: Setup Erlang
+        id: setup-beam
         uses: ./.github/actions/setup-beam
         with:
           otp-version: ${{ matrix.otp-version }}
@@ -34,10 +35,21 @@
       - name: Setup MSVC toolchain
         if: ${{ matrix.os == 'windows-latest' }}
         uses: ./.github/actions/msvc-dev-cmd
+      - name: Check coding style with erlfmt
+        if: ${{ matrix.os == 'ubuntu-latest' }}
+        run: rebar3 fmt --check
+        continue-on-error: true
       - name: Compile
         run: rebar3 compile
       - name: EUnit tests
         run: rebar3 eunit
+      - name: Restore dialyzer PLT from cache
+        uses: actions/cache@v2
+        with:
+          path: ~/.cache/rebar3/rebar3_*_plt
+          key: ${{ runner.os }}-${{ steps.setup-beam.outputs.otp-version }}
+      - name: Run dialyzer analysis
+        run: rebar3 as test dialyzer
       - name: Setup tmate session on job failure
         uses: ./.github/actions/tmate
         if: ${{ failure() }}
diff --git a/rebar.config b/rebar.config
index 83a227f..d9512ae 100644
--- a/rebar.config
+++ b/rebar.config
@@ -24,7 +24,6 @@
     % Production compilation
     {"(linux|solaris|darwin|freebsd)", "CFLAGS", "$CFLAGS -Wall -Werror -DNDEBUG -O3"},
     {"win32", "CFLAGS", "$CFLAGS /O2 /DNDEBUG /Wall"}
-
 ]}.
 
 {eunit_opts, [
diff --git a/src/b64url.erl b/src/b64url.erl
index 2eb4b82..6e6ddac 100644
--- a/src/b64url.erl
+++ b/src/b64url.erl
@@ -13,22 +13,18 @@
 -module(b64url).
 -on_load(init/0).
 
-
 -export([
     encode/1,
     decode/1
 ]).
 
-
 % Internal sanity checks
 -export([
     check_tables/0
 ]).
 
-
 -define(NOT_LOADED, not_loaded(?LINE)).
 
-
 -spec encode(iodata()) -> binary().
 encode(IoData) ->
     case encode_init(IoData) of
@@ -38,7 +34,6 @@
             encode_loop(IoData, St)
     end.
 
-
 -spec decode(iodata()) -> binary() | {error, any()}.
 decode(IoData) ->
     case decode_init(IoData) of
@@ -54,19 +49,18 @@
 check_tables() ->
     ?NOT_LOADED.
 
-
 init() ->
-    PrivDir = case code:priv_dir(?MODULE) of
-        {error, _} ->
-            EbinDir = filename:dirname(code:which(?MODULE)),
-            AppPath = filename:dirname(EbinDir),
-            filename:join(AppPath, "priv");
-        Path ->
-            Path
-    end,
+    PrivDir =
+        case code:priv_dir(?MODULE) of
+            {error, _} ->
+                EbinDir = filename:dirname(code:which(?MODULE)),
+                AppPath = filename:dirname(EbinDir),
+                filename:join(AppPath, "priv");
+            Path ->
+                Path
+        end,
     erlang:load_nif(filename:join(PrivDir, "b64url"), 0).
 
-
 encode_loop(IoData, St) ->
     case encode_cont(IoData, St) of
         {ok, Bin} ->
@@ -75,7 +69,6 @@
             encode_loop(IoData, St)
     end.
 
-
 decode_loop(IoData, St) ->
     case decode_cont(IoData, St) of
         {ok, Bin} ->
@@ -86,13 +79,10 @@
             decode_loop(IoData, St)
     end.
 
-
 encode_init(_) -> ?NOT_LOADED.
 encode_cont(_, _) -> ?NOT_LOADED.
 decode_init(_) -> ?NOT_LOADED.
 decode_cont(_, _) -> ?NOT_LOADED.
 
-
 not_loaded(Line) ->
     erlang:nif_error({not_loaded, [{module, ?MODULE}, {line, Line}]}).
-
diff --git a/test/b64url_tests.erl b/test/b64url_tests.erl
index 27e69db..5e8e575 100644
--- a/test/b64url_tests.erl
+++ b/test/b64url_tests.erl
@@ -1,90 +1,93 @@
 -module(b64url_tests).
 
-
 -include_lib("eunit/include/eunit.hrl").
 
-
 -define(MAX_SIZE, 6401).
 -define(NUM_TESTS, 500).
 
-
 table_test() ->
     ?assertEqual(ok, b64url:check_tables()).
 
-
 encode_binary_test() ->
-    lists:foreach(fun(_) ->
-        Bin = gen_binary(),
-        A = couch_encode_base64url(Bin),
-        B = b64url:encode(Bin),
-        ?assertEqual(A, B)
-    end, lists:seq(1, ?NUM_TESTS)).
-
+    lists:foreach(
+        fun(_) ->
+            Bin = gen_binary(),
+            A = couch_encode_base64url(Bin),
+            B = b64url:encode(Bin),
+            ?assertEqual(A, B)
+        end,
+        lists:seq(1, ?NUM_TESTS)
+    ).
 
 encode_iolist_test() ->
-    lists:foreach(fun(_) ->
-        IoList = shallow_iolist(),
-        A = couch_encode_base64url(iolist_to_binary(IoList)),
-        B = b64url:encode(IoList),
-        ?assertEqual(A, B)
-    end, lists:seq(1, ?NUM_TESTS)).
-
+    lists:foreach(
+        fun(_) ->
+            IoList = shallow_iolist(),
+            A = couch_encode_base64url(iolist_to_binary(IoList)),
+            B = b64url:encode(IoList),
+            ?assertEqual(A, B)
+        end,
+        lists:seq(1, ?NUM_TESTS)
+    ).
 
 decode_binary_test() ->
-    lists:foreach(fun(_) ->
-        Bin = gen_binary(),
-        B64UrlBin = couch_encode_base64url(Bin),
-        Dec = b64url:decode(B64UrlBin),
-        ?assertEqual(Bin, Dec)
-    end, lists:seq(1, ?NUM_TESTS)).
-
+    lists:foreach(
+        fun(_) ->
+            Bin = gen_binary(),
+            B64UrlBin = couch_encode_base64url(Bin),
+            Dec = b64url:decode(B64UrlBin),
+            ?assertEqual(Bin, Dec)
+        end,
+        lists:seq(1, ?NUM_TESTS)
+    ).
 
 decode_iolist_test() ->
-    lists:foreach(fun(_) ->
-        IoList = shallow_b64_iolist(),
-        A = couch_decode_base64url(iolist_to_binary(IoList)),
-        B = b64url:decode(IoList),
-        ?assertEqual(A, B)
-    end, lists:seq(1, ?NUM_TESTS)).
-
+    lists:foreach(
+        fun(_) ->
+            IoList = shallow_b64_iolist(),
+            A = couch_decode_base64url(iolist_to_binary(IoList)),
+            B = b64url:decode(IoList),
+            ?assertEqual(A, B)
+        end,
+        lists:seq(1, ?NUM_TESTS)
+    ).
 
 decode_binary_error_test() ->
-    lists:foreach(fun(_) ->
-        {ErrBin, BlockPos} = bad_binary(),
-        Dec = b64url:decode(ErrBin),
-        ?assertEqual({error, {bad_block, BlockPos}}, Dec)
-    end, lists:seq(1, ?NUM_TESTS)).
-
+    lists:foreach(
+        fun(_) ->
+            {ErrBin, BlockPos} = bad_binary(),
+            Dec = b64url:decode(ErrBin),
+            ?assertEqual({error, {bad_block, BlockPos}}, Dec)
+        end,
+        lists:seq(1, ?NUM_TESTS)
+    ).
 
 decode_bad_length_test() ->
-    lists:foreach(fun(_) ->
-        Bin = bad_len_binary(),
-        ?assertError(badarg, b64url:decode(Bin))
-    end, lists:seq(1, ?NUM_TESTS)).
-
+    lists:foreach(
+        fun(_) ->
+            Bin = bad_len_binary(),
+            ?assertError(badarg, b64url:decode(Bin))
+        end,
+        lists:seq(1, ?NUM_TESTS)
+    ).
 
 gen_binary() ->
     % -1 to allow for 0 length
     Length = rand:uniform(?MAX_SIZE) - 1,
     crypto:strong_rand_bytes(Length).
 
-
 shallow_iolist() ->
     to_iolist(gen_binary()).
 
-
 shallow_b64_iolist() ->
     to_iolist(couch_encode_base64url(gen_binary())).
 
-
 bad_binary() ->
     insert_error(gen_binary()).
 
-
 bad_len_binary() ->
     make_bad_len(gen_binary()).
 
-
 to_iolist(<<>>) ->
     case rand:uniform(2) of
         1 -> <<>>;
@@ -98,11 +101,10 @@
             [to_iolist(First), Second];
         2 ->
             [First, to_iolist(Second)];
-        3->
+        3 ->
             [First, Second]
     end.
 
-
 insert_error(B) when is_binary(B), size(B) < 2 ->
     case rand:uniform(2) of
         1 -> {<<122, 255>>, 0};
@@ -114,7 +116,6 @@
     <<First:S/binary, _:1/binary, Second/binary>> = B64,
     {<<First:S/binary, 255, Second/binary>>, 4 * (S div 4)}.
 
-
 make_bad_len(Bin) when size(Bin) rem 4 == 1 ->
     Bin;
 make_bad_len(Bin) when size(Bin) rem 4 == 2 ->
@@ -124,19 +125,16 @@
 make_bad_len(Bin) when size(Bin) rem 4 == 0 ->
     <<"A", Bin/binary>>.
 
-
 % These functions are copy/pasted from couch_util to avoid
 % the direct dependency. The goal of this project is to replace
 % these in couch_util anyway so when that happens they'll only
 % exist here for these tests.
 
-
 couch_encode_base64url(Url) ->
     Url1 = iolist_to_binary(re:replace(base64:encode(Url), "=+$", "")),
     Url2 = iolist_to_binary(re:replace(Url1, "/", "_", [global])),
     iolist_to_binary(re:replace(Url2, "\\+", "-", [global])).
 
-
 couch_decode_base64url(Url64) ->
     Url1 = re:replace(iolist_to_binary(Url64), "-", "+", [global]),
     Url2 = iolist_to_binary(