Open
Description
Hi @aj-foster 👋🏾,
Tldr
I wanted to add another/dynamic key in %Field{...}
in OpenAPI.Processor
, but I'm certain I'm doing the wrong way
Why did I do this?
Everytime I generate my spec file, defaults that are described aren't picked up in defstruct
:
# generated
...
defstruct [
:default_sorting_field,
:enable_nested_fields,
:fields,
:name,
:symbols_to_index,
:token_separators
]
...
I was expecting:
# generated
...
defstruct [
:fields,
:name,
default_sorting_field: "",
enable_nested_fields: false,
symbols_to_index: [],
token_separators: []
]
...
Then I saw this doc statement for run/1
function:
Warning
This functions is used by the main OpenAPI
module. It is unlikely that you will call this
function directly, unless you are reimplementing one of the core functions. If this happens,
please share your use-case with the maintainers; a plugin might be warranted.
I'm just confused how to do it using the provided callbacks, so that I can use the plugin way.
Here's what I did
- Add mix deps
{:oapi_generator, path: "/path/to/local/open-api-generator"}
(was just confirming this in local dev) - (
OpenAPI.Processor
) added another key in field insidedefp process_schema_fields
, which is used by the parentrun
function. But the problem here is, "If this happens, please share your use-case with the maintainers; a plugin might be warranted." - Add also that key in
OpenAPI.Processor.Schema.Field
The codes
processor.ex
I edited the processor.ex inside the deps folder
defmodule OpenAPI.Processor do
...
alias OpenAPI.Processor.Format
alias OpenAPI.Processor.Operation
alias OpenAPI.Processor.Schema.Field
alias OpenAPI.Processor.Operation.Param
alias OpenAPI.Processor.Schema
# ...reduced for brevity
# around this line
@spec process_schema_fields(State.t(), SchemaSpec.t(), reference, MapSet.t()) ::
{State.t(), [Field.t()]}
defp process_schema_fields(state, schema_spec, parent_ref, seen_refs) do
%SchemaSpec{properties: properties, required: required} = schema_spec
for {field_name, field_spec} <- properties, reduce: {state, []} do
{state, fields} ->
+ default =
+ case field_spec do
+ %SchemaSpec{default: default} -> default
+ rest -> rest
+ end
nullable? =
case field_spec do
%SchemaSpec{nullable: nullable?} -> nullable?
{:ref, _} -> false
end
# ...reduced for brevity
field = %Field{
name: field_name,
nullable: nullable?,
private: false,
required: required?,
type: type,
+ default: default
}
{state, [field | fields]}
end
end
end
end
schema.ex
defmodule OpenAPI.Renderer.Schema do
...
@spec render_struct(State.t(), [Schema.t()]) :: Macro.t()
def render_struct(state, schemas) do
fields =
Enum.map(schemas, & &1.fields)
|> List.insert_at(0, extra_fields(state))
|> List.flatten()
+ |> Enum.map(fn field ->
+ if not is_nil(field.default) do
+ {String.to_atom(field.name), field.default}
+ else
+ String.to_atom(field.name)
+ end
+ end)
|> Enum.sort()
|> Enum.dedup()
quote do
defstruct unquote(fields)
end
|> Util.put_newlines()
end
...
end
field.ex
defmodule OpenAPI.Processor.Schema.Field do
...
alias OpenAPI.Processor.Type
@typedoc "Processed field data used by the renderer"
@type t :: %__MODULE__{
name: String.t(),
nullable: boolean,
private: boolean,
required: boolean,
type: Type.t(),
+ default: any()
}
defstruct name: nil,
nullable: false,
private: false,
required: false,
type: nil,
+ default: nil
end
Metadata
Metadata
Assignees
Labels
No labels