Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the base types used by Kadena #14

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ kadena-*.tar

# Temporary files, for example, from tests.
/tmp/

# Dialyzer plt files
/priv/plts
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
elixir 1.13
15 changes: 15 additions & 0 deletions lib/types/base16_string.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
defmodule Kadena.Types.Base16String do
@moduledoc """
`Base16String` struct definition.
"""

@behaviour Kadena.Types.Spec

@type t :: %__MODULE__{value: String.t()}

defstruct [:value]

@impl true
def new(str) when is_binary(str), do: %__MODULE__{value: str}
def new(_str), do: {:error, :invalid_string}
end
15 changes: 15 additions & 0 deletions lib/types/base64_url.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
defmodule Kadena.Types.Base64Url do
@moduledoc """
`Base64Url` struct definition.
"""

@behaviour Kadena.Types.Spec

@type t :: %__MODULE__{url: String.t()}

defstruct [:url]

@impl true
def new(str) when is_binary(str), do: %__MODULE__{url: str}
def new(_str), do: {:error, :invalid_string}
end
17 changes: 17 additions & 0 deletions lib/types/pact_decimal.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
defmodule Kadena.Types.PactDecimal do
@moduledoc """
`PactDecimal` struct definition.
"""

alias Decimal

@behaviour Kadena.Types.Spec

@type t :: %__MODULE__{value: Decimal.t(), raw_value: String.t()}

defstruct [:value, :raw_value]

@impl true
def new(str) when is_binary(str), do: %__MODULE__{value: Decimal.new(str), raw_value: str}
def new(_str), do: {:error, :invalid_decimal}
end
17 changes: 17 additions & 0 deletions lib/types/pact_int.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
defmodule Kadena.Types.PactInt do
@moduledoc """
`PactInt` struct definition.
"""

@behaviour Kadena.Types.Spec

@type t :: %__MODULE__{value: integer(), raw_value: String.t()}

defstruct [:value, :raw_value]

@impl true
def new(value) when is_integer(value),
do: %__MODULE__{value: value, raw_value: to_string(value)}

def new(_value), do: {:error, :invalid_int}
end
22 changes: 22 additions & 0 deletions lib/types/pact_literal.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
defmodule Kadena.Types.PactLiteral do
@moduledoc """
`PactLiteral` struct definition.
"""
alias Kadena.Types.{PactInt, PactDecimal}

@behaviour Kadena.Types.Spec

@type literal :: PactInt.t() | PactDecimal.t() | String.t() | number() | boolean()

@type t :: %__MODULE__{literal: literal()}

defstruct [:literal]

@impl true
def new(%PactInt{} = pact_int), do: %__MODULE__{literal: pact_int}
def new(%PactDecimal{} = pact_decimal), do: %__MODULE__{literal: pact_decimal}
def new(str) when is_binary(str), do: %__MODULE__{literal: str}
def new(number) when is_number(number), do: %__MODULE__{literal: number}
def new(bool) when is_boolean(bool), do: %__MODULE__{literal: bool}
def new(_literal), do: {:error, :invalid_literal}
end
25 changes: 25 additions & 0 deletions lib/types/pact_literals_list.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
defmodule Kadena.Types.PactLiteralsList do
@moduledoc """
`PactLiteralsList` struct definition.
"""
alias Kadena.Types.PactLiteral

@behaviour Kadena.Types.Spec

@type literals :: list(PactLiteral.t())

@type t :: %__MODULE__{list: literals()}

defstruct list: []

@impl true
def new(literals), do: build_list(%__MODULE__{}, literals)

@spec build_list(list :: t(), literals :: literals()) :: t()
defp build_list(list, []), do: list

defp build_list(%__MODULE__{list: list}, [%PactLiteral{} = literal | rest]),
do: build_list(%__MODULE__{list: [literal | list]}, rest)

defp build_list(_list, _literals), do: {:error, :invalid_literal}
end
19 changes: 19 additions & 0 deletions lib/types/pact_value.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
defmodule Kadena.Types.PactValue do
@moduledoc """
`PactValue` structure definition.
"""
alias Kadena.Types.{PactLiteral, PactLiteralsList}

@behaviour Kadena.Types.Spec

@type pact_value :: PactLiteral.t() | PactLiteralsList.t()

@type t :: %__MODULE__{value: pact_value()}

defstruct [:value]

@impl true
def new(%PactLiteral{} = literal), do: %__MODULE__{value: literal}
def new(%PactLiteralsList{} = literal_list), do: %__MODULE__{value: literal_list}
def new(_value), do: {:error, :invalid_value}
end
19 changes: 19 additions & 0 deletions lib/types/signature.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
defmodule Kadena.Types.Signature do
@moduledoc """
`Signature` struct definition.
"""

@behaviour Kadena.Types.Spec

@type sig :: String.t() | nil

@type t :: %__MODULE__{sig: sig()}

defstruct [:sig]

@impl true
def new(sig \\ nil)
def new(nil), do: %__MODULE__{}
def new(sig) when is_binary(sig), do: %__MODULE__{sig: sig}
def new(_sig), do: {:error, :invalid_signature}
end
33 changes: 33 additions & 0 deletions lib/types/signed_signature_with_hash.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
defmodule Kadena.Types.SignedSignatureWithHash do
@moduledoc """
`SignedSignatureWithHash` struct definition.
"""
alias Kadena.Types.Signature

@behaviour Kadena.Types.Spec

@type sig :: Signature.t()

@type t :: %__MODULE__{
hash: String.t(),
sig: sig(),
pub_key: String.t()
}

defstruct [:hash, :sig, :pub_key]

@impl true
def new(args) do
hash = Keyword.get(args, :hash)
sig = Keyword.get(args, :sig)
pub_key = Keyword.get(args, :pub_key)

with hash when is_binary(hash) <- hash,
pub_key when is_binary(pub_key) <- pub_key,
%Signature{} <- sig do
%__MODULE__{hash: hash, sig: sig, pub_key: pub_key}
else
_error -> {:error, :invalid_signature}
end
end
end
9 changes: 9 additions & 0 deletions lib/types/spec.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule Kadena.Types.Spec do
@moduledoc """
Defines base types constructions.
"""

@type error :: {:error, atom()}

@callback new(any()) :: struct() | error()
end
1 change: 1 addition & 0 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ defmodule Kadena.MixProject do
defp deps do
[
{:credo, "~> 1.6", only: [:dev, :test], runtime: false},
{:decimal, "~> 2.0"},
{:dialyxir, "~> 1.0", only: [:dev, :test], runtime: false},
{:ex_doc, "~> 0.24", only: :dev, runtime: false}
]
Expand Down
1 change: 1 addition & 0 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
%{
"bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"},
"credo": {:hex, :credo, "1.6.7", "323f5734350fd23a456f2688b9430e7d517afb313fbd38671b8a4449798a7854", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "41e110bfb007f7eda7f897c10bf019ceab9a0b269ce79f015d54b0dcf4fc7dd3"},
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
"dialyxir": {:hex, :dialyxir, "1.2.0", "58344b3e87c2e7095304c81a9ae65cb68b613e28340690dfe1a5597fd08dec37", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "61072136427a851674cab81762be4dbeae7679f85b1272b6d25c3a839aff8463"},
"earmark_parser": {:hex, :earmark_parser, "1.4.26", "f4291134583f373c7d8755566122908eb9662df4c4b63caa66a0eabe06569b0a", [:mix], [], "hexpm", "48d460899f8a0c52c5470676611c01f64f3337bad0b26ddab43648428d94aabc"},
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
Expand Down
23 changes: 23 additions & 0 deletions test/types/base16_string_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
defmodule Kadena.Types.Base16StringTest do
@moduledoc """
`Base16String` struct definition tests.
"""

use ExUnit.Case

alias Kadena.Types.Base16String

describe "new/1" do
test "with a valid string value" do
%Base16String{value: "string"} = Base16String.new("string")
end

test "with an invalid atom value" do
{:error, :invalid_string} = Base16String.new(:atom)
end

test "with an invalid nil value" do
{:error, :invalid_string} = Base16String.new(nil)
end
end
end
23 changes: 23 additions & 0 deletions test/types/base64_url_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
defmodule Kadena.Types.Base64UrlTest do
@moduledoc """
`Base64Url` struct definition tests.
"""

use ExUnit.Case

alias Kadena.Types.Base64Url

describe "new/1" do
test "With valid url" do
%Base64Url{url: "valid_url"} = Base64Url.new("valid_url")
end

test "With invalid url" do
{:error, :invalid_string} = Base64Url.new(:atom)
end

test "With nil url" do
{:error, :invalid_string} = Base64Url.new(nil)
end
end
end
40 changes: 40 additions & 0 deletions test/types/pact_decimal_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
defmodule Kadena.Types.PactDecimalTest do
@moduledoc """
`PactDecimal` struct definition tests.
"""

use ExUnit.Case

alias Kadena.Types.PactDecimal

describe "new/1" do
test "With valid value" do
expected_value = Decimal.new("4.3333333")
%PactDecimal{value: ^expected_value, raw_value: "4.3333333"} = PactDecimal.new("4.3333333")
end

test "With nil value" do
{:error, :invalid_decimal} = PactDecimal.new(nil)
end

test "With atom value" do
{:error, :invalid_decimal} = PactDecimal.new(:atom)
end

test "With list of nil" do
{:error, :invalid_decimal} = PactDecimal.new([nil])
end

test "With one list item with valid value" do
{:error, :invalid_decimal} = PactDecimal.new(["2.333", nil, true])
end

test "With each list item with invalid value" do
{:error, :invalid_decimal} = PactDecimal.new([:atom, nil, true])
end

test "With empty list value" do
{:error, :invalid_decimal} = PactDecimal.new([])
end
end
end
39 changes: 39 additions & 0 deletions test/types/pact_int_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
defmodule Kadena.Types.PactIntTest do
@moduledoc """
`PactInt` struct definition tests.
"""

use ExUnit.Case

alias Kadena.Types.PactInt

describe "new/1" do
test "With valid integer" do
%PactInt{value: 500, raw_value: "500"} = PactInt.new(500)
end

test "With nil value" do
{:error, :invalid_int} = PactInt.new(nil)
end

test "With atom value" do
{:error, :invalid_int} = PactInt.new(:atom)
end

test "With list of nil" do
{:error, :invalid_int} = PactInt.new([nil])
end

test "With one list item with valid value" do
{:error, :invalid_int} = PactInt.new([2333, nil, true])
end

test "With each list item with invalid value" do
{:error, :invalid_int} = PactInt.new([:atom, nil, true])
end

test "With empty list value" do
{:error, :invalid_int} = PactInt.new([])
end
end
end
Loading