Skip to content

Commit

Permalink
Make it so 🚀
Browse files Browse the repository at this point in the history
  • Loading branch information
cabol committed Sep 7, 2020
1 parent 002ccc9 commit 2f9c2fa
Show file tree
Hide file tree
Showing 17 changed files with 1,002 additions and 25 deletions.
31 changes: 31 additions & 0 deletions .credo.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
%{
configs: [
%{
name: "default",
files: %{
included: ["lib/", "src/", "test/", "benchmarks/"],
excluded: [~r"/_build/", ~r"/deps/"]
},
color: true,
checks: [
## Design Checks
{Credo.Check.Design.AliasUsage, priority: :low},

# Deactivate due to they're not compatible with current Elixir version
{Credo.Check.Refactor.MapInto, false},
{Credo.Check.Warning.LazyLogging, false},

## Readability Checks
{Credo.Check.Readability.MaxLineLength, priority: :low, max_length: 100},

## Refactoring Opportunities
{Credo.Check.Refactor.LongQuoteBlocks, false},
{Credo.Check.Refactor.CyclomaticComplexity, max_complexity: 15},

## TODO and FIXME do not cause the build to fail
{Credo.Check.Design.TagTODO, exit_status: 0},
{Credo.Check.Design.TagFIXME, exit_status: 0}
]
}
]
}
1 change: 1 addition & 0 deletions .dialyzer_ignore.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
4 changes: 4 additions & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Used by "mix format"
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]
74 changes: 74 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: CI

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
nebulex_test:
name: 'ExBits Test (Elixir ${{ matrix.elixir }} OTP ${{ matrix.otp }})'

strategy:
matrix:
elixir:
- '1.10.x'
- '1.9.x'
otp:
- '22.x'

runs-on: ubuntu-latest

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MIX_ENV: test

steps:
- uses: actions/checkout@v2

- uses: actions/setup-elixir@v1
with:
otp-version: '${{ matrix.otp }}'
elixir-version: '${{ matrix.elixir }}'

- uses: actions/cache@v1
with:
path: deps
key: ${{ runner.os }}-mix-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}
restore-keys: |
${{ runner.os }}-mix-
- uses: actions/cache@v1
with:
path: _build
key: ${{ runner.os }}-build-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}
restore-keys: |
${{ runner.os }}-build-
- name: Install Dependencies
run: mix deps.get

- name: Compile Code
run: mix compile --warnings-as-errors

- name: Check Format
run: mix format --check-formatted

- name: Check Style
run: mix credo --strict

- name: Tests and Coverage
run: |
epmd -daemon
mix coveralls.github
- uses: actions/cache@v1
with:
path: priv/plts
key: ${{ runner.os }}-plt-v1-${{ env.MIX_ENV }}
restore-keys: |
${{ runner.os }}-plt-v1
- name: Dialyzer
run: mix dialyzer --format short
32 changes: 30 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,38 @@
# The directory Mix will write compiled artifacts to.
/_build

# If you run "mix test --cover", coverage assets end up here.
/cover

# The directory Mix downloads your dependencies sources to.
/deps

# Where 3rd-party dependencies like ExDoc output generated docs.
/doc
/docs
/benchmarks
!/benchmarks/benchmark.exs

# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch

# Dialyzer
/priv

# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump

# Also ignore archive artifacts (built via "mix archive.build").
*.ez

# Others
*.o
*.beam
/config/*.secret.exs
.elixir_ls/
*.plt
erl_crash.dump
.DS_Store
._*
/tmp*
.elixir*
.vs*
/priv
21 changes: 0 additions & 21 deletions LICENSE

This file was deleted.

47 changes: 45 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,45 @@
# ex_bits
Toolkit and DSL for encoding/decoding bitstring in Elixir
# ExBits
### Toolkit and DSL for encoding/decoding bitstring in Elixir.

![CI](https://github.com/cabol/ex_bits/workflows/CI/badge.svg)

> **NOTE:** It's still a WIP!
## Installation

You need to add `ex_bits` as a dependency to your `mix.exs` file.

```elixir
def deps do
[
{:ex_bits, "~> 0.1.0"}
]
end
```

## Contributing

Contributions to ExBits are very welcome and appreciated!

Use the [issue tracker](https://github.com/cabol/ex_bits/issues) for bug reports
or feature requests. Open a [pull request](https://github.com/cabol/ex_bits/pulls)
when you are ready to contribute.

When submitting a pull request you should not update the [CHANGELOG.md](CHANGELOG.md),
and also make sure you test your changes thoroughly, include unit tests
alongside new or changed code.

Before to submit a PR it is highly recommended to run:

* `mix format` to format the code properly.
* `MIX_ENV=test mix credo --strict` to find code style issues.
* `mix coveralls.html && open cover/excoveralls.html` to run tests and check
out code coverage (expected 100%).
* `MIX_ENV=test mix dialyzer` to run dialyzer for type checking; might take a
while on the first invocation.

## Copyright and License

Copyright (c) 2020, Carlos Bolaños.

ExBits source code is licensed under the [MIT License](LICENSE).
11 changes: 11 additions & 0 deletions coveralls.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"coverage_options": {
"treat_no_relevant_lines_as_covered": true,
"minimum_coverage": 100
},

"skip_files": [
"lib/ex_bits/helpers.ex",
"test/support/*"
]
}
50 changes: 50 additions & 0 deletions lib/ex_bits.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
defmodule ExBits do
@moduledoc """
TODO: Add docs.
"""

use Bitwise
use ExBits.Helpers

@typedoc "Codable data types"
@type bit_data :: integer | float | binary | bitstring | byte | char

## API

@spec encode_bits(bit_data, Keyword.t()) :: bitstring
def encode_bits(input, opts \\ []) do
type = Keyword.get(opts, :type, :integer)
sign = Keyword.get(opts, :sign, :unsigned)
endian = Keyword.get(opts, :endian, :big)
size = Keyword.get(opts, :size)

size =
cond do
is_nil(size) and is_integer(input) -> 8
is_nil(size) and is_float(input) -> 64
true -> size
end

encode_bits(input, size, type, sign, endian)
end

def decode_bits(input, opts \\ []) do
type = Keyword.get(opts, :type, :integer)
sign = Keyword.get(opts, :sign, :unsigned)
endian = Keyword.get(opts, :endian, :big)
size = opts[:size] || byte_size(input) * 8

decode_bits(input, size, type, sign, endian)
end

@spec count_ones(integer) :: integer
def count_ones(integer) when is_integer(integer) do
count_ones(integer, 0)
end

defp count_ones(0, count), do: count

defp count_ones(integer, count) do
count_ones(integer &&& integer - 1, count + 1)
end
end
Loading

0 comments on commit 2f9c2fa

Please sign in to comment.