pylon / spect Goto Github PK
View Code? Open in Web Editor NEWType specification extensions for Elixir
Type specification extensions for Elixir
Using the decimal-2.0.0 package:
iex(20)> Spect.to_spec(Decimal.new("1.23"), Decimal)
{:ok, #Decimal<1.23>}
iex(21)> Spect.to_spec(Decimal.new("-1.23"), Decimal)
{:error,
%Spect.ConvertError{
message: "expected: union of [{:integer, 0, 1}, {:op, 74, :-, {:integer, 74, 1}}], found: -1"
}}
My guess is that it's due to sign()
in decimal-2.0.0
being defined as
@type sign :: 1 | -1
which seems to be an invalid typespec.
When attempting to use a parameterized type from a remote module a MatchError
is throw. Parameterized types in the local module seem to work fine. Example below:
defmodule Types do
@type maybe(t) :: t | nil
end
defmodule OtherModule do
@type bar :: Types.maybe(binary())
end
Error:
{:error, %MatchError{term: [{:atom, 0, Types}, {:atom, 0, :maybe}, [{:type, 40, :binary, []}]]}}
Really loving Spect
by the way! Thanks for creating it!
==> spect
Compiling 1 file (.ex)
warning: Kernel.Typespec.beam_types/1 is deprecated. Use Code.Typespec.fetch_types/1 instead
lib/spect.ex:83: Spect.__load_types_memoize/1
Current behaviour:
> ~D[2021-01-01] |> Jason.encode! |> Spect.to_spec!(Date)
** (Spect.ConvertError) expected: map, found: "\"2021-01-01\""
(spect 0.4.1) lib/spect.ex:443: Spect.to_map!/4
Would be nice if it tried to convert the date string to a Date.t()
instead of failing immediately.
For example, given the following struct definition:
typed_struct enforce: true do
field :foo, String.t()
end
Spect will happily accept an empty map as valid:
> Spect.to_spec(%{}, __MODULE__)
{:ok, %__MODULE__{foo: nil}}
Parameterized types seem to be working locally, but are failing with remote types. I tried to distill this example down as best I could.
With this code...
defmodule MyTypes do
@type maybe(t) :: t | nil
end
defmodule MyModule do
@type rating :: 1 | 2 | 3 | 4 | 5
@type t :: %__MODULE__{
rating: MyTypes.maybe(rating())
}
defstruct rating: nil
end
defmodule MyModule2 do
@typep maybe(t) :: t | nil
@type rating :: 1 | 2 | 3 | 4 | 5
@type t :: %__MODULE__{
rating: maybe(rating())
}
defstruct rating: nil
end
Using MyModule2
with the local parameterized type, things work as expected:
iex(8)> Spect.to_spec(%{"rating" => 5}, MyModule2)
{:ok, %MyModule2{rating: 5}}
Using MyModule
with the remote parameterized type, things fail:
iex(9)> Spect.to_spec(%{"rating" => 5}, MyModule)
{:error,
%Spect.ConvertError{
message: "expected: union of [{:var, 2, :t}, {:atom, 0, nil}], found: 5"
}}
Unrelated, but in my code I have some pretty large nested structs and it can be difficult to figure out which field is failing to decode. It turns into trial-and-error of removing fields until it passes. If it's possible, it would be great to call out in the error message specifically which field is failing at the deepest level.
In order for Spect
to work in a mix release, the strip_beams
release option must be set to false
in a project's mix.exs
release configuration. Example:
def project do
[
app: :my_app,
version: "0.1.0",
elixir: "~> 1.11",
elixirc_paths: elixirc_paths(Mix.env()),
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
start_permanent: Mix.env() == :prod,
aliases: aliases(),
deps: deps(),
default_release: :my_app,
releases: [
my_app: [
# this is needed for spect to work
strip_beams: false
]
]
]
end
Without strip_beams
set to false, calls to Spect.to_spec!()
will fail with module not found: ...
errors since the debug_info
chunk will be missing.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.