Skip to content

Commit

Permalink
Initial Val types (#24)
Browse files Browse the repository at this point in the history
* Add initial val types

* Add requested changes and stellar_sdk version update

* Update spec

---------

Co-authored-by: CristhianRodriguezMolina <CristhianRodriguezMolina@users.noreply.github.com>
  • Loading branch information
Odraxs and CristhianRodriguezMolina authored May 2, 2023
1 parent 648fb8c commit 5227530
Show file tree
Hide file tree
Showing 33 changed files with 1,115 additions and 1 deletion.
43 changes: 43 additions & 0 deletions lib/types/address.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
defmodule Soroban.Types.Address do
@moduledoc """
`Address` struct definition.
"""

@behaviour Soroban.Types.Spec

alias Stellar.TxBuild.{SCAddress, SCVal}

defstruct [:value]

@type value :: binary()
@type type :: atom()
@type errors :: atom()
@type validation :: {:ok, value()} | {:error, errors()}
@type t :: %__MODULE__{value: value()}

@impl true
def new(value) when is_binary(value) do
with {:ok, value} <- validate_address(value) do
%__MODULE__{value: value}
end
end

def new(_value), do: {:error, :invalid}

@impl true
def to_sc_val(%__MODULE__{value: value}) do
value
|> SCAddress.new()
|> (&SCVal.new(address: &1)).()
end

def to_sc_val(_error), do: {:error, :invalid_struct_address}

@spec validate_address(value :: value()) :: validation()
defp validate_address(value) do
case SCAddress.new(value) do
%SCAddress{} -> {:ok, value}
_error -> {:error, :invalid_address}
end
end
end
23 changes: 23 additions & 0 deletions lib/types/bool.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
defmodule Soroban.Types.Bool do
@moduledoc """
`Bool` struct definition.
"""

@behaviour Soroban.Types.Spec

alias Stellar.TxBuild.SCVal

defstruct [:value]

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

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

def new(_value), do: {:error, :invalid}

@impl true
def to_sc_val(%__MODULE__{value: value}), do: SCVal.new(bool: value)
def to_sc_val(_error), do: {:error, :invalid_struct_bool}
end
23 changes: 23 additions & 0 deletions lib/types/bytes.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
defmodule Soroban.Types.Bytes do
@moduledoc """
`Bytes` struct definition.
"""

@behaviour Soroban.Types.Spec

alias Stellar.TxBuild.SCVal

defstruct [:value]

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

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

def new(_value), do: {:error, :invalid}

@impl true
def to_sc_val(%__MODULE__{value: value}), do: SCVal.new(bytes: value)
def to_sc_val(_error), do: {:error, :invalid_struct_bytes}
end
36 changes: 36 additions & 0 deletions lib/types/duration.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
defmodule Soroban.Types.Duration do
@moduledoc """
`Duration` struct definition.
"""

@behaviour Soroban.Types.Spec

alias Stellar.TxBuild.SCVal

defstruct [:value]

@type value :: non_neg_integer()
@type errors :: atom()
@type validation :: {:ok, value()} | {:error, errors()}
@type t :: %__MODULE__{value: value()}

@int_range 0..18_446_744_073_709_551_615

@impl true
def new(value) when is_integer(value) do
case validate_duration_range(value) do
{:ok, duration} -> %__MODULE__{value: duration}
error -> error
end
end

def new(_value), do: {:error, :invalid}

@impl true
def to_sc_val(%__MODULE__{value: value}), do: SCVal.new(duration: value)
def to_sc_val(_error), do: {:error, :invalid_struct_duration}

@spec validate_duration_range(value :: value()) :: validation()
defp validate_duration_range(value) when value in @int_range, do: {:ok, value}
defp validate_duration_range(_value), do: {:error, :not_in_duration_range}
end
40 changes: 40 additions & 0 deletions lib/types/int128.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
defmodule Soroban.Types.Int128 do
@moduledoc """
`Int128` struct definition.
"""

@behaviour Soroban.Types.Spec

alias Stellar.TxBuild.SCVal

defstruct [:value]

@type value :: integer()
@type errors :: atom()
@type validation :: {:ok, value()} | {:error, errors()}
@type t :: %__MODULE__{value: value()}

@int_range -170_141_183_460_469_231_731_687_303_715_884_105_728..170_141_183_460_469_231_731_687_303_715_884_105_727

@impl true
def new(value) when is_integer(value) do
case validate_int128_range(value) do
{:ok, i128} -> %__MODULE__{value: i128}
error -> error
end
end

def new(_value), do: {:error, :invalid}

@impl true
def to_sc_val(%__MODULE__{value: value}) do
<<hi::size(64), lo::size(64)>> = <<value::size(128)>>
SCVal.new(i128: %{lo: lo, hi: hi})
end

def to_sc_val(_error), do: {:error, :invalid_struct_int128}

@spec validate_int128_range(value :: value()) :: validation()
defp validate_int128_range(value) when value in @int_range, do: {:ok, value}
defp validate_int128_range(_value), do: {:error, :not_in_i128_range}
end
22 changes: 22 additions & 0 deletions lib/types/int256.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
defmodule Soroban.Types.Int256 do
@moduledoc """
`Int256` struct definition.
"""

@behaviour Soroban.Types.Spec

alias Stellar.TxBuild.SCVal

defstruct [:value]

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

@impl true
def new(value) when is_integer(value), do: %__MODULE__{value: value}
def new(_value), do: {:error, :invalid}

@impl true
def to_sc_val(%__MODULE__{value: value}), do: SCVal.new(i256: <<value::size(256)>>)
def to_sc_val(_error), do: {:error, :invalid_struct_int256}
end
36 changes: 36 additions & 0 deletions lib/types/int32.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
defmodule Soroban.Types.Int32 do
@moduledoc """
`Int32` struct definition.
"""

@behaviour Soroban.Types.Spec

alias Stellar.TxBuild.SCVal

defstruct [:value]

@type value :: integer()
@type errors :: atom()
@type validation :: {:ok, value()} | {:error, errors()}
@type t :: %__MODULE__{value: value()}

@int_range -2_147_483_648..2_147_483_647

@impl true
def new(value) when is_integer(value) do
case validate_int32_range(value) do
{:ok, i32} -> %__MODULE__{value: i32}
error -> error
end
end

def new(_value), do: {:error, :invalid}

@impl true
def to_sc_val(%__MODULE__{value: value}), do: SCVal.new(i32: value)
def to_sc_val(_error), do: {:error, :invalid_struct_int32}

@spec validate_int32_range(value :: value()) :: validation()
defp validate_int32_range(value) when value in @int_range, do: {:ok, value}
defp validate_int32_range(_value), do: {:error, :not_in_i32_range}
end
36 changes: 36 additions & 0 deletions lib/types/int64.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
defmodule Soroban.Types.Int64 do
@moduledoc """
`Int64` struct definition.
"""

@behaviour Soroban.Types.Spec

alias Stellar.TxBuild.SCVal

defstruct [:value]

@type value :: integer()
@type errors :: atom()
@type validation :: {:ok, value()} | {:error, errors()}
@type t :: %__MODULE__{value: value()}

@int_range -9_223_372_036_854_775_808..9_223_372_036_854_775_807

@impl true
def new(value) when is_integer(value) do
case validate_int64_range(value) do
{:ok, i64} -> %__MODULE__{value: i64}
error -> error
end
end

def new(_value), do: {:error, :invalid}

@impl true
def to_sc_val(%__MODULE__{value: value}), do: SCVal.new(i64: value)
def to_sc_val(_error), do: {:error, :invalid_struct_int64}

@spec validate_int64_range(value :: value()) :: validation()
defp validate_int64_range(value) when value in @int_range, do: {:ok, value}
defp validate_int64_range(_value), do: {:error, :not_in_i64_range}
end
12 changes: 12 additions & 0 deletions lib/types/spec.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
defmodule Soroban.Types.Spec do
@moduledoc """
Defines base types constructions.
"""
alias Stellar.TxBuild.SCVal

@type error :: {:error, atom()}
@type sc_val :: SCVal.t()

@callback new(any()) :: struct() | error()
@callback to_sc_val(struct()) :: sc_val()
end
23 changes: 23 additions & 0 deletions lib/types/string.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
defmodule Soroban.Types.String do
@moduledoc """
`String` struct definition.
"""

@behaviour Soroban.Types.Spec

alias Stellar.TxBuild.SCVal

defstruct [:value]

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

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

def new(_value), do: {:error, :invalid}

@impl true
def to_sc_val(%__MODULE__{value: value}), do: SCVal.new(string: value)
def to_sc_val(_error), do: {:error, :invalid_struct_string}
end
23 changes: 23 additions & 0 deletions lib/types/symbol.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
defmodule Soroban.Types.Symbol do
@moduledoc """
`Symbol` struct definition.
"""

@behaviour Soroban.Types.Spec

alias Stellar.TxBuild.SCVal

defstruct [:value]

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

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

def new(_value), do: {:error, :invalid}

@impl true
def to_sc_val(%__MODULE__{value: value}), do: SCVal.new(symbol: value)
def to_sc_val(_error), do: {:error, :invalid_struct_symbol}
end
36 changes: 36 additions & 0 deletions lib/types/time_point.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
defmodule Soroban.Types.TimePoint do
@moduledoc """
`TimePoint` struct definition.
"""

@behaviour Soroban.Types.Spec

alias Stellar.TxBuild.SCVal

defstruct [:value]

@type value :: non_neg_integer()
@type errors :: atom()
@type validation :: {:ok, value()} | {:error, errors()}
@type t :: %__MODULE__{value: value()}

@int_range 0..18_446_744_073_709_551_615

@impl true
def new(value) when is_integer(value) do
case validate_time_point_range(value) do
{:ok, time_point} -> %__MODULE__{value: time_point}
error -> error
end
end

def new(_value), do: {:error, :invalid}

@impl true
def to_sc_val(%__MODULE__{value: value}), do: SCVal.new(time_point: value)
def to_sc_val(_error), do: {:error, :invalid_struct_time_point}

@spec validate_time_point_range(value :: value()) :: validation()
defp validate_time_point_range(value) when value in @int_range, do: {:ok, value}
defp validate_time_point_range(_value), do: {:error, :not_in_time_point_range}
end
Loading

0 comments on commit 5227530

Please sign in to comment.