Aurora.Uix.Parser behaviour (Aurora UIX v0.1.4)

Copy Markdown

Core parsing interface for resource configuration in Aurora.Uix.

Defines the behaviour contract and orchestration logic for converting resource definitions (Ecto schemas or Ash resources) into structured configuration maps that enable dynamic UI generation. Combines schema metadata extraction with context-based CRUD function discovery.

Key Features

  • Schema metadata extraction (names, titles, sources, primary keys)
  • Automatic CRUD function discovery for Context and Ash integrations
  • Flexible parser composition through behaviour-based architecture
  • Support for multiple backend types (:ctx for Context, :ash for Ash Framework)
  • Option resolution through cascading parser modules

Parser Architecture

The parsing process delegates to specialized parser modules:

  1. Common Parser (Aurora.Uix.Parsers.Common) - Extracts schema-derived properties like module names, sources, titles, and primary keys from Ecto schemas.

  2. Context Parser Defaults (Aurora.Uix.Integration.ContextParserDefaults) - Dispatches to backend-specific implementations for CRUD function discovery:

Behaviour Callbacks

Parser implementations must provide:

  • get_options/0 - Returns list of option keys the parser supports
  • option_value/4 - Resolves default values for configuration options
  • fill_missing_options/1 - Fills in any missing configuration options after parsing

Key Constraints

  • Requires valid resource configuration with :schema key
  • Context-based parsers require :type, :context keys in resource configuration
  • Parser resolution happens at compile-time through application configuration
  • Options are merged with resource defaults before processing

Summary

Callbacks

Fills in missing configuration options based on parsed values and resource configuration.

Returns the list of supported configuration option keys for the parser.

Resolves the default value for a configuration key.

Functions

Parses resource configuration into a structured map for UI rendering.

Callbacks

fill_missing_options(parsed_opts, resource_config)

@callback fill_missing_options(parsed_opts :: map(), resource_config :: map()) :: map()

Fills in missing configuration options based on parsed values and resource configuration.

This callback can be used to perform any final adjustments or fill in derived options after the main parsing process has completed. It receives the fully parsed options and can return an updated map with any additional options or adjustments needed for UI rendering.

Parameters

  • parsed_opts (map()) - The fully parsed options after processing all parsers. Contains all resolved configuration values.
  • resource_config (map()) - The original resource configuration passed to parse/2. Contains the initial schema, type, context, and any default options.

Returns

map() - An updated map of options with any missing values filled in or adjustments made. This allows for final transformations or derived values to be added after the main parsing process.

get_options(resource_config, opts)

@callback get_options(resource_config :: map(), opts :: map()) :: [atom()]

Returns the list of supported configuration option keys for the parser.

Parser implementations use this to declare which configuration options they can resolve. The keys are used by parse/2 to iterate and resolve values through option_value/4.

Parameters

  • resource_config (map()) - The resource configuration map passed to parse/2, containing keys like :schema, :type, :context, and any default options. This allows parsers to conditionally declare supported options based on the resource configuration.
  • opts (map()) - The resource configuration map passed to parse/2, containing keys like :schema, :type, :context, and any default options. This allows parsers to conditionally declare supported options based on the resource configuration.

Returns

list(atom()) - List of configuration option keys supported by the parser.

Examples

iex> Aurora.Uix.Parsers.Common.get_options()
[:module, :module_name, :name, :source, :source_key, :title, :primary_key]

option_value(parsed_opts, resource_config, opts, key)

@callback option_value(
  parsed_opts :: map(),
  resource_config :: map(),
  opts :: keyword(),
  key :: atom()
) :: term()

Resolves the default value for a configuration key.

Called by the parsing process to determine the value for each option key. Implementations can inspect parsed options, resource configuration, and raw options to compute values.

Parameters

  • parsed_opts (map()) - Accumulator of previously parsed options. Useful for deriving values based on other resolved options.
  • resource_config (map()) - Resource configuration containing :schema, :type, :context, and other metadata.
  • opts (keyword()) - Raw un-parsed keyword options passed to parse/2.
  • key (atom()) - Configuration key to resolve (e.g., :module, :list_function).

Returns

term() - The resolved value for the given key. Type depends on the key being resolved.

Functions

parse(resource_config, opts \\ [])

@spec parse(
  map(),
  keyword()
) :: map()

Parses resource configuration into a structured map for UI rendering.

Orchestrates the parsing process by delegating to Common and ContextParserDefaults parsers, combining schema metadata extraction with CRUD function discovery.

Parameters

  • resource_config (map()) - Resource configuration containing:
    • :schema (module()) - Ecto schema or Ash resource module
    • :type (atom()) - Backend type (:ctx or :ash)
    • :context (module()) - Context
    • :opts (keyword()) - Default options
  • opts (keyword()) - Additional configuration options merged with resource defaults. Options are delegated to parser modules:

Returns

map() - Parsed configuration containing schema metadata, CRUD function references, and UI template settings.

Examples

iex> Aurora.Uix.Parser.parse(%{schema: Aurora.Uix.Guides.Accounts.User, type: :ctx, context: Aurora.Uix.Guides.Accounts, name: :user, opts: []}, [])
%{
  module: "user",
  name: "User",
  title: "Users",
  source: "users",
  module_name: "User",
  list_function: %Aurora.Uix.Integration.Connector{
    type: :ctx,
    crud_spec: %Aurora.Uix.Integration.Ctx.CrudSpec{
      function_spec: &Aurora.Uix.Guides.Accounts.list_users/1,
      auix_action_name: :list_function
    }
  },
  list_function_paginated: %Aurora.Uix.Integration.Connector{
    type: :ctx,
    crud_spec: %Aurora.Uix.Integration.Ctx.CrudSpec{
      function_spec: &Aurora.Uix.Guides.Accounts.list_users_paginated/1,
      auix_action_name: :list_function_paginated
    }
  },
  get_function: %Aurora.Uix.Integration.Connector{
    type: :ctx,
    crud_spec: %Aurora.Uix.Integration.Ctx.CrudSpec{
      function_spec: &Aurora.Uix.Guides.Accounts.get_user/2,
      auix_action_name: :get_function
    }
  },
  delete_function: %Aurora.Uix.Integration.Connector{
    type: :ctx,
    crud_spec: %Aurora.Uix.Integration.Ctx.CrudSpec{
      function_spec: &Aurora.Uix.Guides.Accounts.delete_user/1,
      auix_action_name: :delete_function
    }
  },
  create_function: %Aurora.Uix.Integration.Connector{
    type: :ctx,
    crud_spec: %Aurora.Uix.Integration.Ctx.CrudSpec{
      function_spec: &Aurora.Uix.Guides.Accounts.create_user/1,
      auix_action_name: :create_function
    }
  },
  update_function: %Aurora.Uix.Integration.Connector{
    type: :ctx,
    crud_spec: %Aurora.Uix.Integration.Ctx.CrudSpec{
      function_spec: &Aurora.Uix.Guides.Accounts.update_user/2,
      auix_action_name: :update_function
    }
  },
  change_function: %Aurora.Uix.Integration.Connector{
    type: :ctx,
    crud_spec: %Aurora.Uix.Integration.Ctx.CrudSpec{
      function_spec: &Aurora.Uix.Guides.Accounts.change_user/2,
      auix_action_name: :change_function
    }
  },
  new_function: %Aurora.Uix.Integration.Connector{
    type: :ctx,
    crud_spec: %Aurora.Uix.Integration.Ctx.CrudSpec{
      function_spec: &Aurora.Uix.Guides.Accounts.new_user/2,
      auix_action_name: :new_function
    }
  },
  primary_key: [:id],
  source_key: :users
}