defmodule OpenAPI.Renderer.State do @moduledoc """ State of the render phase of code generation This struct is created at the beginning of the render phase using data from the overall generator `OpenAPI.State`. It has the following fields: * `files`: Map of module names and their associated `t:OpenAPI.Renderer.File.t/0` structs. This map is built using the `operations` and `schemas` data. * `implementation`: Module configured as the implementation of the renderer (defaults to `OpenAPI.Renderer`). Callbacks must use this field when calling other render callbacks. * `operations`: List of `t:OpenAPI.Processor.Operation.t/0` structs processed in the previous phase. These operations may appear in any order due to map key ordering. * `profile`: Name of the active configuration profile. Callbacks must use this field when looking up configuration from the application environment. * `schemas`: Map of schema references to their `t:OpenAPI.Processor.Schema.t/0` structs processed in the previous phase. The reference-keyed map is included to make it easier for callbacks to look up a schema by its reference, as this is often how operations will refer to them. All of this state is managed by the code generator, and it is unlikely that a callback would need to transform this struct directly. """ alias OpenAPI.Processor.Operation alias OpenAPI.Processor.Schema alias OpenAPI.Renderer.File @typedoc """ Render phase state See module documentation for additional information. """ @type t :: %__MODULE__{ files: %{module => File.t()}, implementation: module, operations: [Operation.t()], profile: atom, schemas: %{reference => Schema.t()} } defstruct [ :files, :implementation, :operations, :profile, :schemas ] @doc false @spec new(OpenAPI.State.t()) :: t def new(state) do %OpenAPI.State{ call: %OpenAPI.Call{profile: profile}, operations: operations, schemas: schemas } = state %__MODULE__{ files: %{}, implementation: implementation(profile), operations: operations, profile: profile, schemas: schemas } end @spec implementation(atom) :: module defp implementation(profile) do Application.get_env(:oapi_generator, profile) |> Keyword.get(:renderer, OpenAPI.Renderer) end @doc false @spec update_files(t, module, Operation.t()) :: t @spec update_files(t, module, Schema.t()) :: t def update_files(%__MODULE__{files: files} = state, module, operation_or_schema) do files = Map.update( files, module, File.new(module, operation_or_schema), &File.add(&1, operation_or_schema) ) %__MODULE__{state | files: files} end defimpl Inspect do import Inspect.Algebra def inspect(renderer_state, _opts) do %OpenAPI.Renderer.State{implementation: implementation} = renderer_state concat([ "#OpenAPI.Renderer.State<", "implementation: ", inspect(implementation), ">" ]) end end end