From f16bc07a73272ef7a32f37103231e3d5eab6e325 Mon Sep 17 00:00:00 2001 From: Ian Harris Date: Fri, 27 Sep 2024 09:00:52 -0700 Subject: [PATCH 01/10] allow setting explicit values for enum --- lib/unifex/code_generators/common.ex | 5 ++++- lib/unifex/specs_dsl.ex | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/unifex/code_generators/common.ex b/lib/unifex/code_generators/common.ex index 5d09397..b852924 100644 --- a/lib/unifex/code_generators/common.ex +++ b/lib/unifex/code_generators/common.ex @@ -81,7 +81,10 @@ defmodule Unifex.CodeGenerators.Common do @spec generate_enum_native_definition(Specs.enum_t(), map) :: CodeGenerator.code_t() def generate_enum_native_definition({enum_name, enum_types}, _ctx) do enum_types = - Enum.map_join(enum_types, ",\n", fn type -> String.upcase("#{enum_name}_#{type}") end) + Enum.map_join(enum_types, ",\n", fn + {type, val} -> String.upcase("#{enum_name}_#{type} = #{val}") + type -> String.upcase("#{enum_name}_#{type}") + end) enum_name = enum_name diff --git a/lib/unifex/specs_dsl.ex b/lib/unifex/specs_dsl.ex index 9b165ab..869298b 100644 --- a/lib/unifex/specs_dsl.ex +++ b/lib/unifex/specs_dsl.ex @@ -265,6 +265,10 @@ defmodule Unifex.Specs.DSL do [type_name] end + defp parse_enum_types({type_name, val}) when is_atom(type_name) and is_integer(val) do + [{type_name, val}] + end + defp parse_enum_types({:|, _meta, [first_arg, second_arg]}) do parse_enum_types(first_arg) ++ parse_enum_types(second_arg) end From 9346be21ec1b8575828157f5707e63ad0c95345c Mon Sep 17 00:00:00 2001 From: Ian Harris Date: Fri, 27 Sep 2024 09:01:14 -0700 Subject: [PATCH 02/10] add test for explicit enum --- test_projects/nif/c_src/example/example.spec.exs | 2 ++ test_projects/nif/test/example_test.exs | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/test_projects/nif/c_src/example/example.spec.exs b/test_projects/nif/c_src/example/example.spec.exs index d8031a7..036b0c2 100644 --- a/test_projects/nif/c_src/example/example.spec.exs +++ b/test_projects/nif/c_src/example/example.spec.exs @@ -78,6 +78,8 @@ test_my_enum docs """ spec test_my_enum(in_enum :: my_enum) :: {:ok :: label, out_enum :: my_enum} +spec my_explicit_enum :: {:a, 1} | :b | {:c, 4} | {:d, 8} + # tests for bugged version of functions returning nil. # these tests should be removed in unifex v2.0.0. For more information check: # https://github.com/membraneframework/membrane_core/issues/758 diff --git a/test_projects/nif/test/example_test.exs b/test_projects/nif/test/example_test.exs index c1c2359..60ffd33 100644 --- a/test_projects/nif/test/example_test.exs +++ b/test_projects/nif/test/example_test.exs @@ -83,6 +83,17 @@ defmodule ExampleTest do end end + test "explicit enum" do + assert {:ok, :a} = Example.test_explicit_enum(:a) + assert {:ok, :b} = Example.test_explicit_enum(:b) + assert {:ok, :c} = Example.test_explicit_enum(:c) + assert {:ok, :d} = Example.test_explicit_enum(:d) + + assert_raise ErlangError, ~r/unifex_parse_arg.*in_enum.*my_explicit_enum/i, fn -> + Example.test_my_explicit_enum(:option_not_mentioned) + end + end + test "nested struct list" do my_struct = %My.Struct{id: 1, name: "Jan Kowlaski", data: [1, 2, 3, 4, 5, 6, 7, 8, 9]} nested_struct_list = %Nested.StructList{id: 1, struct_list: [my_struct]} From e43a420c3bc62ae7c02c75b570fc8062e93f806e Mon Sep 17 00:00:00 2001 From: Ian Harris Date: Fri, 27 Sep 2024 09:03:04 -0700 Subject: [PATCH 03/10] format --- test_projects/nif/test/example_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_projects/nif/test/example_test.exs b/test_projects/nif/test/example_test.exs index 60ffd33..ff813c9 100644 --- a/test_projects/nif/test/example_test.exs +++ b/test_projects/nif/test/example_test.exs @@ -99,7 +99,7 @@ defmodule ExampleTest do nested_struct_list = %Nested.StructList{id: 1, struct_list: [my_struct]} assert {:ok, ^nested_struct_list} = Example.test_nested_struct_list(nested_struct_list) end - + # tests for bugged version of functions returning nil. # these tests should be removed in unifex v2.0.0. For more information check: # https://github.com/membraneframework/membrane_core/issues/758 From 380e42e318893fb3e15075055f54ce0a975da8c3 Mon Sep 17 00:00:00 2001 From: Ian Harris Date: Tue, 29 Oct 2024 10:21:04 -0700 Subject: [PATCH 04/10] change syntax for explicit enum values --- lib/unifex/specs_dsl.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/unifex/specs_dsl.ex b/lib/unifex/specs_dsl.ex index 869298b..b3de863 100644 --- a/lib/unifex/specs_dsl.ex +++ b/lib/unifex/specs_dsl.ex @@ -265,8 +265,8 @@ defmodule Unifex.Specs.DSL do [type_name] end - defp parse_enum_types({type_name, val}) when is_atom(type_name) and is_integer(val) do - [{type_name, val}] + defp parse_enum_types({:enum_value, _meta, [type_name, value]}) when is_atom(type_name) and is_integer(value) do + [{type_name, value}] end defp parse_enum_types({:|, _meta, [first_arg, second_arg]}) do From b5556f8b15f2c22c86bb4197ac3fe8c17ce2c898 Mon Sep 17 00:00:00 2001 From: Ian Harris Date: Tue, 29 Oct 2024 10:21:46 -0700 Subject: [PATCH 05/10] format --- lib/unifex/specs_dsl.ex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/unifex/specs_dsl.ex b/lib/unifex/specs_dsl.ex index b3de863..9a8bd2e 100644 --- a/lib/unifex/specs_dsl.ex +++ b/lib/unifex/specs_dsl.ex @@ -265,7 +265,8 @@ defmodule Unifex.Specs.DSL do [type_name] end - defp parse_enum_types({:enum_value, _meta, [type_name, value]}) when is_atom(type_name) and is_integer(value) do + defp parse_enum_types({:enum_value, _meta, [type_name, value]}) + when is_atom(type_name) and is_integer(value) do [{type_name, value}] end From 69881fd31d70f2d7add438abd25e5e112c5cbb76 Mon Sep 17 00:00:00 2001 From: Ian Harris Date: Tue, 29 Oct 2024 10:25:13 -0700 Subject: [PATCH 06/10] add doc for enum_value --- lib/unifex/specs_dsl.ex | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/unifex/specs_dsl.ex b/lib/unifex/specs_dsl.ex index 9a8bd2e..85dbb38 100644 --- a/lib/unifex/specs_dsl.ex +++ b/lib/unifex/specs_dsl.ex @@ -235,6 +235,10 @@ defmodule Unifex.Specs.DSL do type my_enum :: :option_one | :option_two | :option_three | ... + Enum constants can be given an explicit value with `enum_value` + + type my_explicit_enum :: enum_value(:option_one, 1) | :option_two | :option_three | ... + Struct or enums specified in such way can be used in like any other supported type, E.g. spec my_function(in_enum :: my_enum) :: {:ok :: label, out_struct :: my_struct} From 5325b8e251e168167544f633b4720224ed41f549 Mon Sep 17 00:00:00 2001 From: Ian Harris Date: Wed, 6 Nov 2024 10:16:10 -0800 Subject: [PATCH 07/10] handle explicit enums in generator --- lib/unifex/code_generator/base_types/enum.ex | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/unifex/code_generator/base_types/enum.ex b/lib/unifex/code_generator/base_types/enum.ex index ca1e8e8..c677c5d 100644 --- a/lib/unifex/code_generator/base_types/enum.ex +++ b/lib/unifex/code_generator/base_types/enum.ex @@ -14,7 +14,7 @@ defmodule Unifex.CodeGenerator.BaseTypes.Enum do @impl true def generate_native_type(ctx) do - ~g<#{ctx.type_spec.name |> Atom.to_string() |> Macro.camelize()}> + ~g<#{ctx.type_spec.name |> enum_to_string() |> Macro.camelize()}> end defmodule NIF do @@ -114,7 +114,7 @@ defmodule Unifex.CodeGenerator.BaseTypes.Enum do enum_name = ctx.type_spec.name ctx.type_spec.types - |> Enum.map(&Atom.to_string/1) + |> Enum.map(&enum_to_string/1) |> Enum.map_join(" else ", fn type -> ~g""" if (strcmp(enum_as_string, "#{type}") == 0) { @@ -134,11 +134,11 @@ defmodule Unifex.CodeGenerator.BaseTypes.Enum do CodeGenerator.code_t() def do_generate_arg_serialize_if_statements(name, ctx, serializer) do {last_type, types} = List.pop_at(ctx.type_spec.types, -1) - last_type = Atom.to_string(last_type) + last_type = enum_to_string(last_type) enum_name = ctx.type_spec.name types - |> Enum.map(&Atom.to_string/1) + |> Enum.map(&enum_to_string/1) |> Enum.map(fn type -> ~g""" if (#{name} == #{String.upcase("#{enum_name}_#{type}")}) { @@ -149,4 +149,7 @@ defmodule Unifex.CodeGenerator.BaseTypes.Enum do |> Enum.concat(["{ #{serializer.(last_type, ctx)} }"]) |> Enum.join(" else ") end + + defp enum_to_string(name) when is_atom(name), do: Atom.to_string(name) + defp enum_to_string({name, _val}) when is_atom(name), do: Atom.to_string(name) end From 4517196e76d3a803e60d6e50b8efab8794eecd54 Mon Sep 17 00:00:00 2001 From: Ian Harris Date: Wed, 6 Nov 2024 10:18:05 -0800 Subject: [PATCH 08/10] fix explicit enum tests --- test_projects/nif/c_src/example/example.c | 4 ++++ test_projects/nif/c_src/example/example.spec.exs | 5 ++++- test_projects/nif/test/example_test.exs | 8 ++++---- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/test_projects/nif/c_src/example/example.c b/test_projects/nif/c_src/example/example.c index 5f58c05..0b09e60 100644 --- a/test_projects/nif/c_src/example/example.c +++ b/test_projects/nif/c_src/example/example.c @@ -74,6 +74,10 @@ UNIFEX_TERM test_my_enum(UnifexEnv *env, MyEnum in_enum) { return test_my_enum_result_ok(env, in_enum); } +UNIFEX_TERM test_my_explicit_enum(UnifexEnv *env, MyExplicitEnum in_enum) { + return test_my_explicit_enum_result_ok(env, in_enum); +} + UNIFEX_TERM test_nested_struct(UnifexEnv *env, nested_struct in_struct) { return test_nested_struct_result_ok(env, in_struct); } diff --git a/test_projects/nif/c_src/example/example.spec.exs b/test_projects/nif/c_src/example/example.spec.exs index 036b0c2..ef54cc0 100644 --- a/test_projects/nif/c_src/example/example.spec.exs +++ b/test_projects/nif/c_src/example/example.spec.exs @@ -73,12 +73,15 @@ spec test_list_of_structs(struct_list :: [simple_struct]) :: {:ok :: label, out_ type my_enum :: :option_one | :option_two | :option_three | :option_four | :option_five +type my_explicit_enum :: enum_value(:a, 1) | :b | enum_value(:c, 4) | enum_value(:d, 8) + @doc """ test_my_enum docs """ spec test_my_enum(in_enum :: my_enum) :: {:ok :: label, out_enum :: my_enum} -spec my_explicit_enum :: {:a, 1} | :b | {:c, 4} | {:d, 8} + +spec test_my_explicit_enum(in_enum :: my_explicit_enum) :: {:ok :: label, out_enum :: my_explicit_enum} # tests for bugged version of functions returning nil. # these tests should be removed in unifex v2.0.0. For more information check: diff --git a/test_projects/nif/test/example_test.exs b/test_projects/nif/test/example_test.exs index ff813c9..b7ba2b5 100644 --- a/test_projects/nif/test/example_test.exs +++ b/test_projects/nif/test/example_test.exs @@ -84,10 +84,10 @@ defmodule ExampleTest do end test "explicit enum" do - assert {:ok, :a} = Example.test_explicit_enum(:a) - assert {:ok, :b} = Example.test_explicit_enum(:b) - assert {:ok, :c} = Example.test_explicit_enum(:c) - assert {:ok, :d} = Example.test_explicit_enum(:d) + assert {:ok, :a} = Example.test_my_explicit_enum(:a) + assert {:ok, :b} = Example.test_my_explicit_enum(:b) + assert {:ok, :c} = Example.test_my_explicit_enum(:c) + assert {:ok, :d} = Example.test_my_explicit_enum(:d) assert_raise ErlangError, ~r/unifex_parse_arg.*in_enum.*my_explicit_enum/i, fn -> Example.test_my_explicit_enum(:option_not_mentioned) From 1d6e60c02b69b779eaeda3828d9327e14dbeca0d Mon Sep 17 00:00:00 2001 From: Ian Harris Date: Wed, 6 Nov 2024 10:18:19 -0800 Subject: [PATCH 09/10] update nif text fixtures for explicit enums --- test/fixtures/nif_ref_generated/nif/example.c | 75 +++++++++++++++++++ .../nif_ref_generated/nif/example.cpp | 75 +++++++++++++++++++ test/fixtures/nif_ref_generated/nif/example.h | 20 +++++ 3 files changed, 170 insertions(+) diff --git a/test/fixtures/nif_ref_generated/nif/example.c b/test/fixtures/nif_ref_generated/nif/example.c index 50b8a82..a0197c4 100644 --- a/test/fixtures/nif_ref_generated/nif/example.c +++ b/test/fixtures/nif_ref_generated/nif/example.c @@ -353,6 +353,35 @@ UNIFEX_TERM test_my_enum_result_ok(UnifexEnv *env, MyEnum out_enum) { }); } +UNIFEX_TERM test_my_explicit_enum_result_ok(UnifexEnv *env, + MyExplicitEnum out_enum) { + return ({ + const ERL_NIF_TERM terms[] = {enif_make_atom(env, "ok"), ({ + ERL_NIF_TERM res; + if (out_enum == MY_EXPLICIT_ENUM_A) { + const char *enum_as_string = "a"; + res = enif_make_atom(env, enum_as_string); + + } else if (out_enum == MY_EXPLICIT_ENUM_B) { + const char *enum_as_string = "b"; + res = enif_make_atom(env, enum_as_string); + + } else if (out_enum == MY_EXPLICIT_ENUM_C) { + const char *enum_as_string = "c"; + res = enif_make_atom(env, enum_as_string); + + } else { + const char *enum_as_string = "d"; + res = enif_make_atom(env, enum_as_string); + } + res; + }) + + }; + enif_make_tuple_from_array(env, terms, 2); + }); +} + UNIFEX_TERM test_nil_bugged_result_nil(UnifexEnv *env) { return enif_make_atom(env, "nil"); } @@ -1253,6 +1282,51 @@ static ERL_NIF_TERM export_test_my_enum(ErlNifEnv *env, int argc, return result; } +static ERL_NIF_TERM export_test_my_explicit_enum(ErlNifEnv *env, int argc, + const ERL_NIF_TERM argv[]) { + UNIFEX_MAYBE_UNUSED(argc); + UNIFEX_MAYBE_UNUSED(argv); + ERL_NIF_TERM result; + UnifexEnv *unifex_env = env; + MyExplicitEnum in_enum; + + if (!({ + int res = 0; + char *enum_as_string = NULL; + + if (unifex_alloc_and_get_atom(env, argv[0], &enum_as_string)) { + if (strcmp(enum_as_string, "a") == 0) { + in_enum = MY_EXPLICIT_ENUM_A; + res = 1; + } else if (strcmp(enum_as_string, "b") == 0) { + in_enum = MY_EXPLICIT_ENUM_B; + res = 1; + } else if (strcmp(enum_as_string, "c") == 0) { + in_enum = MY_EXPLICIT_ENUM_C; + res = 1; + } else if (strcmp(enum_as_string, "d") == 0) { + in_enum = MY_EXPLICIT_ENUM_D; + res = 1; + } + + if (enum_as_string != NULL) { + unifex_free((void *)enum_as_string); + } + } + + res; + })) { + result = unifex_raise_args_error(env, "in_enum", ":my_explicit_enum"); + goto exit_export_test_my_explicit_enum; + } + + result = test_my_explicit_enum(unifex_env, in_enum); + goto exit_export_test_my_explicit_enum; +exit_export_test_my_explicit_enum: + + return result; +} + static ERL_NIF_TERM export_test_nil_bugged(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { UNIFEX_MAYBE_UNUSED(argc); @@ -1305,6 +1379,7 @@ static ErlNifFunc nif_funcs[] = { {"unifex_test_nested_struct", 1, export_test_nested_struct, 0}, {"unifex_test_list_of_structs", 1, export_test_list_of_structs, 0}, {"unifex_test_my_enum", 1, export_test_my_enum, 0}, + {"unifex_test_my_explicit_enum", 1, export_test_my_explicit_enum, 0}, {"unifex_test_nil_bugged", 0, export_test_nil_bugged, 0}, {"unifex_test_nil_tuple_bugged", 1, export_test_nil_tuple_bugged, 0}}; diff --git a/test/fixtures/nif_ref_generated/nif/example.cpp b/test/fixtures/nif_ref_generated/nif/example.cpp index 50b8a82..a0197c4 100644 --- a/test/fixtures/nif_ref_generated/nif/example.cpp +++ b/test/fixtures/nif_ref_generated/nif/example.cpp @@ -353,6 +353,35 @@ UNIFEX_TERM test_my_enum_result_ok(UnifexEnv *env, MyEnum out_enum) { }); } +UNIFEX_TERM test_my_explicit_enum_result_ok(UnifexEnv *env, + MyExplicitEnum out_enum) { + return ({ + const ERL_NIF_TERM terms[] = {enif_make_atom(env, "ok"), ({ + ERL_NIF_TERM res; + if (out_enum == MY_EXPLICIT_ENUM_A) { + const char *enum_as_string = "a"; + res = enif_make_atom(env, enum_as_string); + + } else if (out_enum == MY_EXPLICIT_ENUM_B) { + const char *enum_as_string = "b"; + res = enif_make_atom(env, enum_as_string); + + } else if (out_enum == MY_EXPLICIT_ENUM_C) { + const char *enum_as_string = "c"; + res = enif_make_atom(env, enum_as_string); + + } else { + const char *enum_as_string = "d"; + res = enif_make_atom(env, enum_as_string); + } + res; + }) + + }; + enif_make_tuple_from_array(env, terms, 2); + }); +} + UNIFEX_TERM test_nil_bugged_result_nil(UnifexEnv *env) { return enif_make_atom(env, "nil"); } @@ -1253,6 +1282,51 @@ static ERL_NIF_TERM export_test_my_enum(ErlNifEnv *env, int argc, return result; } +static ERL_NIF_TERM export_test_my_explicit_enum(ErlNifEnv *env, int argc, + const ERL_NIF_TERM argv[]) { + UNIFEX_MAYBE_UNUSED(argc); + UNIFEX_MAYBE_UNUSED(argv); + ERL_NIF_TERM result; + UnifexEnv *unifex_env = env; + MyExplicitEnum in_enum; + + if (!({ + int res = 0; + char *enum_as_string = NULL; + + if (unifex_alloc_and_get_atom(env, argv[0], &enum_as_string)) { + if (strcmp(enum_as_string, "a") == 0) { + in_enum = MY_EXPLICIT_ENUM_A; + res = 1; + } else if (strcmp(enum_as_string, "b") == 0) { + in_enum = MY_EXPLICIT_ENUM_B; + res = 1; + } else if (strcmp(enum_as_string, "c") == 0) { + in_enum = MY_EXPLICIT_ENUM_C; + res = 1; + } else if (strcmp(enum_as_string, "d") == 0) { + in_enum = MY_EXPLICIT_ENUM_D; + res = 1; + } + + if (enum_as_string != NULL) { + unifex_free((void *)enum_as_string); + } + } + + res; + })) { + result = unifex_raise_args_error(env, "in_enum", ":my_explicit_enum"); + goto exit_export_test_my_explicit_enum; + } + + result = test_my_explicit_enum(unifex_env, in_enum); + goto exit_export_test_my_explicit_enum; +exit_export_test_my_explicit_enum: + + return result; +} + static ERL_NIF_TERM export_test_nil_bugged(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { UNIFEX_MAYBE_UNUSED(argc); @@ -1305,6 +1379,7 @@ static ErlNifFunc nif_funcs[] = { {"unifex_test_nested_struct", 1, export_test_nested_struct, 0}, {"unifex_test_list_of_structs", 1, export_test_list_of_structs, 0}, {"unifex_test_my_enum", 1, export_test_my_enum, 0}, + {"unifex_test_my_explicit_enum", 1, export_test_my_explicit_enum, 0}, {"unifex_test_nil_bugged", 0, export_test_nil_bugged, 0}, {"unifex_test_nil_tuple_bugged", 1, export_test_nil_tuple_bugged, 0}}; diff --git a/test/fixtures/nif_ref_generated/nif/example.h b/test/fixtures/nif_ref_generated/nif/example.h index 86a27f2..b6d209b 100644 --- a/test/fixtures/nif_ref_generated/nif/example.h +++ b/test/fixtures/nif_ref_generated/nif/example.h @@ -64,6 +64,23 @@ enum MyEnum_t { typedef enum MyEnum_t MyEnum; #endif +#ifdef __cplusplus +enum MyExplicitEnum { + MY_EXPLICIT_ENUM_A = 1, + MY_EXPLICIT_ENUM_B, + MY_EXPLICIT_ENUM_C = 4, + MY_EXPLICIT_ENUM_D = 8 +}; +#else +enum MyExplicitEnum_t { + MY_EXPLICIT_ENUM_A = 1, + MY_EXPLICIT_ENUM_B, + MY_EXPLICIT_ENUM_C = 4, + MY_EXPLICIT_ENUM_D = 8 +}; +typedef enum MyExplicitEnum_t MyExplicitEnum; +#endif + #ifdef __cplusplus struct my_struct { int id; @@ -148,6 +165,7 @@ UNIFEX_TERM test_nested_struct(UnifexEnv *env, nested_struct in_struct); UNIFEX_TERM test_list_of_structs(UnifexEnv *env, simple_struct *struct_list, unsigned int struct_list_length); UNIFEX_TERM test_my_enum(UnifexEnv *env, MyEnum in_enum); +UNIFEX_TERM test_my_explicit_enum(UnifexEnv *env, MyExplicitEnum in_enum); UNIFEX_TERM test_nil_bugged(UnifexEnv *env); UNIFEX_TERM test_nil_tuple_bugged(UnifexEnv *env, int in_int); @@ -188,6 +206,8 @@ UNIFEX_TERM test_list_of_structs_result_ok(UnifexEnv *env, simple_struct const *out_struct_list, unsigned int out_struct_list_length); UNIFEX_TERM test_my_enum_result_ok(UnifexEnv *env, MyEnum out_enum); +UNIFEX_TERM test_my_explicit_enum_result_ok(UnifexEnv *env, + MyExplicitEnum out_enum); UNIFEX_TERM test_nil_bugged_result_nil(UnifexEnv *env); UNIFEX_TERM test_nil_tuple_bugged_result_nil(UnifexEnv *env, int out_int); From 3bca956b1eb605afd5d54e10af9cae55794b1dad Mon Sep 17 00:00:00 2001 From: Ian Harris Date: Thu, 7 Nov 2024 17:00:55 -0800 Subject: [PATCH 10/10] add info about atoms for explicit enums --- lib/unifex/specs_dsl.ex | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/unifex/specs_dsl.ex b/lib/unifex/specs_dsl.ex index 85dbb38..e979ac4 100644 --- a/lib/unifex/specs_dsl.ex +++ b/lib/unifex/specs_dsl.ex @@ -239,6 +239,9 @@ defmodule Unifex.Specs.DSL do type my_explicit_enum :: enum_value(:option_one, 1) | :option_two | :option_three | ... + The numeric value assigned to any enum constant can only be used from C/C++. + In Elixir, the atom must be used. + Struct or enums specified in such way can be used in like any other supported type, E.g. spec my_function(in_enum :: my_enum) :: {:ok :: label, out_struct :: my_struct}