AshReports.RenderContext (ash_reports v0.1.0)
Immutable context structure for managing render state and data transformation.
The RenderContext serves as the central data structure for the Phase 3.1 Renderer Interface, providing a comprehensive context for rendering operations that includes report metadata, processed data, variable values, layout information, and rendering configuration.
Key Features
- Immutable State: All context operations return new context instances
- Data Integration: Seamless integration with Phase 2 DataLoader results
- Layout Management: Support for band-based layout calculations
- Variable Resolution: Access to resolved variable values from VariableState
- Error Context: Comprehensive error tracking and recovery
- Type Safety: Strict type definitions for reliable rendering
Context Structure
The RenderContext contains:
- Report Definition: The report struct with bands, elements, and metadata
- Processed Data: Records from DataLoader with group and variable processing
- Internationalization: Locale information, text direction, and formatting metadata
- Layout State: Current layout calculations and positioning information
- Render Configuration: Output format, styling, and rendering options
- Variable Values: Resolved variable values from Phase 2 processing
- Group State: Current group processing state and break information
- Error State: Any errors encountered during rendering
Usage Patterns
Basic Context Creation
context = RenderContext.new(report, data_result)With Custom Configuration
config = %RenderConfig{
format: :html,
page_size: {8.5, 11},
margins: {0.5, 0.5, 0.5, 0.5}
}
context = RenderContext.new(report, data_result, config)Context Transformation
context
|> RenderContext.set_current_band(band)
|> RenderContext.add_layout_info(layout_data)
|> RenderContext.update_variable_context(new_values)Locale Management
# Create context with specific locale
config = %{locale: "fr", format: :html}
context = RenderContext.new(report, data_result, config)
# Change locale during rendering
context = RenderContext.set_locale(context, "de")
# Get locale information
locale = RenderContext.get_locale(context)
direction = RenderContext.get_text_direction(context)
is_rtl = RenderContext.rtl?(context)Error Handling
case RenderContext.validate(context) do
{:ok, validated_context} -> proceed_with_rendering(validated_context)
{:error, validation_errors} -> handle_errors(validation_errors)
endIntegration with Phase 2
RenderContext seamlessly integrates with DataLoader results:
{:ok, data_result} = DataLoader.load_report(domain, :sales_report, params)
context = RenderContext.from_data_result(report, data_result)
Summary
Functions
Adds an error to the context.
Adds a rendered element to the context.
Adds a warning to the context.
Creates a RenderContext from a DataLoader result.
Gets the current record or a field from the current record.
Gets the current locale for the context.
Gets locale-specific metadata for formatting.
Gets the next record in the sequence.
Gets the text direction for the current locale.
Gets a variable value from the context.
Checks if there are more records to process.
Gets CSS classes appropriate for the current locale.
Creates a new RenderContext from a report and data result.
Removes an element from the pending elements list.
Resets the context for a new rendering pass.
Determines if the context uses a right-to-left locale.
Sets the current band being rendered.
Sets the current group being processed.
Sets the current record being processed.
Sets the locale for the context and updates related locale metadata.
Updates the layout state with new layout information.
Updates the locale metadata in the context.
Updates the current rendering position.
Validates the context for rendering operations.
Types
@type t() :: %AshReports.RenderContext{ config: RenderConfig.t(), created_at: DateTime.t(), current_band: AshReports.Band.t() | nil, current_group: AshReports.Group.t() | nil, current_position: %{x: number(), y: number()}, current_record: map() | nil, current_record_index: non_neg_integer(), data_result: map(), errors: [map()], groups: %{required(term()) => map()}, layout_state: map(), locale: String.t(), locale_metadata: map(), metadata: map(), page_dimensions: %{width: number(), height: number()}, pending_elements: [AshReports.Element.t()], records: [map()], rendered_elements: [map()], report: AshReports.Report.t(), text_direction: String.t(), updated_at: DateTime.t(), variables: %{required(atom()) => term()}, warnings: [map()] }
Functions
Adds an error to the context.
Examples
error = %{type: :layout_error, message: "Element overflow", element: element}
context = RenderContext.add_error(context, error)
Adds a rendered element to the context.
Examples
rendered_element = %{type: :label, content: "Total", position: {100, 50}}
context = RenderContext.add_rendered_element(context, rendered_element)
Adds a warning to the context.
Examples
warning = %{type: :performance_warning, message: "Large dataset detected"}
context = RenderContext.add_warning(context, warning)
@spec from_data_result(AshReports.Report.t(), map(), map()) :: t()
Creates a RenderContext from a DataLoader result.
Convenience function for creating context from Phase 2 DataLoader output.
Examples
{:ok, data_result} = DataLoader.load_report(domain, :report_name, params)
context = RenderContext.from_data_result(report, data_result)
Gets the current record or a field from the current record.
Examples
record = RenderContext.get_current_record(context)
name = RenderContext.get_current_record(context, :customer_name)
Gets the current locale for the context.
Examples
locale = RenderContext.get_locale(context)
Gets locale-specific metadata for formatting.
Examples
metadata = RenderContext.get_locale_metadata(context)
# => %{decimal_separator: ".", thousands_separator: ",", ...}
Gets the next record in the sequence.
Examples
case RenderContext.get_next_record(context) do
{:ok, next_record, new_context} -> process_record(next_record, new_context)
{:error, :no_more_records} -> finish_rendering()
end
Gets the text direction for the current locale.
Examples
direction = RenderContext.get_text_direction(context)
# => "ltr" or "rtl"
Gets a variable value from the context.
Examples
total = RenderContext.get_variable(context, :total_amount)
count = RenderContext.get_variable(context, :record_count, 0)
Checks if there are more records to process.
Examples
if RenderContext.has_more_records?(context) do
process_next_record(context)
end
Gets CSS classes appropriate for the current locale.
Examples
classes = RenderContext.locale_css_classes(context)
# => ["dir-ltr", "locale-en"]
@spec new(AshReports.Report.t(), map(), map()) :: t()
Creates a new RenderContext from a report and data result.
Examples
context = RenderContext.new(report, data_result)
context = RenderContext.new(report, data_result, config)
@spec remove_pending_element(t(), AshReports.Element.t()) :: t()
Removes an element from the pending elements list.
Examples
context = RenderContext.remove_pending_element(context, element)
Resets the context for a new rendering pass.
Examples
fresh_context = RenderContext.reset_for_new_pass(context)
Determines if the context uses a right-to-left locale.
Examples
RenderContext.rtl?(context)
# => true or false
@spec set_current_band(t(), AshReports.Band.t()) :: t()
Sets the current band being rendered.
Examples
context = RenderContext.set_current_band(context, band)
@spec set_current_group(t(), AshReports.Group.t()) :: t()
Sets the current group being processed.
Examples
context = RenderContext.set_current_group(context, group)
@spec set_current_record(t(), map(), non_neg_integer()) :: t()
Sets the current record being processed.
Examples
context = RenderContext.set_current_record(context, record, index)
Sets the locale for the context and updates related locale metadata.
Examples
context = RenderContext.set_locale(context, "fr")
Updates the layout state with new layout information.
Examples
layout_info = %{band_height: 50, element_positions: positions}
context = RenderContext.update_layout_state(context, layout_info)
Updates the locale metadata in the context.
Examples
metadata = %{custom_format: "yyyy-MM-dd"}
context = RenderContext.update_locale_metadata(context, metadata)
Updates the current rendering position.
Examples
context = RenderContext.update_position(context, %{x: 100, y: 200})
Validates the context for rendering operations.
Checks that all required data is present and valid for rendering.
Examples
case RenderContext.validate(context) do
{:ok, context} -> proceed_with_rendering(context)
{:error, errors} -> handle_validation_errors(errors)
end