Skip to content

Commit a1cf929

Browse files
committed
Use ABI.Parser in place of former parsing routines
1 parent 7147b40 commit a1cf929

File tree

2 files changed

+21
-63
lines changed

2 files changed

+21
-63
lines changed

lib/abi.ex

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ defmodule ABI do
2828
def encode(function_signature, data) do
2929
ABI.TypeEncoder.encode(
3030
data,
31-
ABI.FunctionSelector.decode(function_signature)
31+
ABI.Parser.parse!(function_signature)
3232
)
3333
end
3434

@@ -50,8 +50,7 @@ defmodule ABI do
5050
def decode(function_signature, data) do
5151
ABI.TypeDecoder.decode(
5252
data,
53-
ABI.FunctionSelector.decode(function_signature)
53+
ABI.Parser.parse!(function_signature)
5454
)
5555
end
56-
5756
end

lib/abi/function_selector.ex

Lines changed: 19 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ defmodule ABI.FunctionSelector do
1919
defstruct [:function, :types, :returns]
2020

2121
@doc """
22-
Decodes a function selector to struct. This is a simple version
23-
and we may opt to do format parsing later.
22+
Decodes a function selector to a struct.
2423
2524
## Examples
2625
@@ -82,23 +81,7 @@ defmodule ABI.FunctionSelector do
8281
}
8382
"""
8483
def decode(signature) do
85-
captures = Regex.named_captures(~r/(?<function>[a-zA-Z_$][a-zA-Z_$0-9]*)?\((?<types>(([^,]+),?)*)\)/, signature)
86-
87-
if captures["function"] != "" do
88-
# Encode as a function call
89-
%ABI.FunctionSelector{
90-
function: captures["function"],
91-
types: decode_raw(captures["types"]),
92-
returns: nil
93-
}
94-
else
95-
# Encode as a tuple
96-
%ABI.FunctionSelector{
97-
function: nil,
98-
types: [{:tuple, decode_raw(captures["types"])}],
99-
returns: nil
100-
}
101-
end
84+
ABI.Parser.parse!(signature, as: :selector)
10285
end
10386

10487
@doc """
@@ -108,55 +91,31 @@ defmodule ABI.FunctionSelector do
10891
10992
iex> ABI.FunctionSelector.decode_raw("string,uint256")
11093
[:string, {:uint, 256}]
94+
95+
iex> ABI.FunctionSelector.decode_raw("")
96+
[]
11197
"""
11298
def decode_raw(type_string) do
113-
type_string
114-
|> String.split(",", trim: true)
115-
|> Enum.map(&decode_type/1)
99+
{:tuple, types} = decode_type("(#{type_string})")
100+
types
116101
end
117102

118-
def decode_type(full_type) do
119-
cond do
120-
# Check for array type
121-
captures = Regex.named_captures(~r/(?<type>[a-z0-9]+)\[(?<element_count>\d*)\]/, full_type) ->
122-
type = decode_type(captures["type"])
123-
124-
if captures["element_count"] != "" do
125-
{element_count, ""} = Integer.parse(captures["element_count"])
126-
127-
{:array, type, element_count}
128-
else
129-
{:array, type}
130-
end
131-
# Check for tuples
132-
captures = Regex.named_captures(~r/\((?<types>[a-z0-9\[\]]+,?)+\)/, full_type) ->
133-
types =
134-
String.split(captures["types"], ",", trim: true)
135-
|> Enum.map(fn type -> decode_type(type) end)
136-
137-
{:tuple, types}
138-
true ->
139-
decode_single_type(full_type)
140-
end
141-
end
103+
@doc """
104+
Decodes the given type-string as a single type.
142105
143-
def decode_single_type("uint" <> size_str) do
144-
size = case size_str do
145-
"" -> 256 # default
146-
_ ->
147-
{size, ""} = Integer.parse(size_str)
106+
## Examples
148107
149-
size
150-
end
108+
iex> ABI.FunctionSelector.decode_type("uint256")
109+
{:uint, 256}
151110
152-
{:uint, size}
153-
end
111+
iex> ABI.FunctionSelector.decode_type("(bool,address)")
112+
{:tuple, [:bool, :address]}
154113
155-
def decode_single_type("bool"), do: :bool
156-
def decode_single_type("string"), do: :string
157-
def decode_single_type("address"), do: :address
158-
def decode_single_type(els) do
159-
raise "Unsupported type: #{els}"
114+
iex> ABI.FunctionSelector.decode_type("address[][3]")
115+
{:array, {:array, :address}, 3}
116+
"""
117+
def decode_type(single_type) do
118+
ABI.Parser.parse!(single_type, as: :type)
160119
end
161120

162121
@doc """

0 commit comments

Comments
 (0)