Delimit.Schema (delimit v0.1.0)

View Source

Defines schema structures and functions for working with delimited data.

This module handles schema definitions, data type conversions, and transformations between delimited data and Elixir structs.

Summary

Types

Options for schema handling.

t()

Schema definition structure.

Functions

Adds an embedded schema to the parent schema.

Adds a field to the schema.

Gets field names in order of definition.

Gets the header prefix for an embedded field.

Gets all embedded fields defined in the schema.

Gets a field by name.

Gets the headers for the schema.

Creates a new schema definition.

Converts a struct or map to a row of values based on the schema.

Converts a row of data to a struct based on the schema.

Converts a field type to an Elixir typespec.

Types

schema_options()

@type schema_options() :: [
  headers: boolean(),
  delimiter: String.t(),
  skip_lines: non_neg_integer(),
  skip_while: (String.t() -> boolean()),
  trim_fields: boolean(),
  nil_on_empty: boolean(),
  line_ending: String.t(),
  format: atom()
]

Options for schema handling.

  • :headers - Whether to include headers in output (default: true)
  • :delimiter - Field delimiter character (default: comma)
  • :skip_lines - Number of lines to skip at beginning of file
  • :skip_while - Function to determine which lines to skip
  • :trim_fields - Whether to trim whitespace from fields (default: true)
  • :nil_on_empty - Convert empty strings to nil (default: true)
  • :line_ending - Line ending character(s) for output
  • :format - Predefined format (:csv, :tsv, :psv) that sets appropriate options

t()

@type t() :: %Delimit.Schema{
  embeds: %{required(atom()) => module()},
  fields: [Delimit.Field.t()],
  module: module(),
  options: schema_options()
}

Schema definition structure.

  • :module - The module associated with the schema
  • :fields - List of field definitions
  • :options - Additional options for the schema
  • :embeds - Map of module references for embedded schemas

Functions

add_embed(schema, name, module, opts \\ [])

@spec add_embed(t(), atom(), module(), Keyword.t()) :: t()

Adds an embedded schema to the parent schema.

Parameters

  • schema - The parent schema to add the embedded schema to
  • name - The name for the embedded schema as an atom
  • module - The module defining the embedded schema
  • opts - Options for the embedded schema

Returns

  • Updated schema structure

add_field(schema, name, type, opts \\ [])

@spec add_field(t(), atom(), atom(), Keyword.t()) :: t()

Adds a field to the schema.

Parameters

  • schema - The schema to add the field to
  • name - The name of the field as an atom
  • type - The type of the field (:string, :integer, etc.)
  • opts - Options for the field

Returns

  • Updated schema structure

field_names(schema)

@spec field_names(t()) :: [atom()]

Gets field names in order of definition.

Parameters

  • schema - The schema definition

Returns

  • List of field names as atoms

get_embed_prefix(field, default_prefix \\ nil)

@spec get_embed_prefix(Delimit.Field.t(), String.t() | nil) :: String.t()

Gets the header prefix for an embedded field.

Parameters

  • field - The embedded field definition
  • default_prefix - Default prefix to use if none specified

Returns

  • String prefix to use for field headers

get_embeds(schema)

@spec get_embeds(t()) :: [Delimit.Field.t()]

Gets all embedded fields defined in the schema.

Parameters

  • schema - The schema definition

Returns

  • List of embedded field definitions

get_field(schema, name)

@spec get_field(t(), atom()) :: Delimit.Field.t() | nil

Gets a field by name.

Parameters

  • schema - The schema definition
  • name - The field name to find

Returns

  • The field definition or nil if not found

headers(schema, prefix \\ nil)

@spec headers(t(), String.t() | nil) :: [String.t()]

Gets the headers for the schema.

Parameters

  • schema - The schema definition
  • prefix - Optional prefix to apply to all headers

Returns

  • List of header strings

Example

iex> schema = Delimit.Schema.new(MyApp.Person)
iex> schema = Delimit.Schema.add_field(schema, :name, :string)
iex> schema = Delimit.Schema.add_field(schema, :age, :integer)
iex> Delimit.Schema.headers(schema)
["name", "age"]

iex> Delimit.Schema.headers(schema, "person_")
["person_name", "person_age"]

new(module, options \\ [])

@spec new(module(), schema_options()) :: t()

Creates a new schema definition.

Parameters

  • module - The module associated with the schema
  • options - Options for the schema

Returns

  • A new schema structure

to_row(schema, struct_or_map, headers \\ nil, header_positions \\ nil)

@spec to_row(t(), struct() | map(), [String.t()] | nil, map() | nil) :: [String.t()]

Converts a struct or map to a row of values based on the schema.

Parameters

  • schema - The schema definition
  • struct_or_map - A struct or map containing field values
  • headers - Optional list of field names to include (in order)

Returns

  • A list of field values in the correct order

Example

iex> schema = Delimit.Schema.new(MyApp.Person)
iex> schema = Delimit.Schema.add_field(schema, :name, :string)
iex> schema = Delimit.Schema.add_field(schema, :age, :integer)
iex> Delimit.Schema.to_row(schema, %MyApp.Person{name: "John Doe", age: 42})
["John Doe", "42"]

to_struct(schema, row, headers \\ nil, cached_positions \\ nil)

@spec to_struct(t(), [String.t()], [String.t()] | nil, map() | nil) :: struct()

Converts a row of data to a struct based on the schema.

Parameters

  • schema - The schema definition
  • row - A list of field values or a map of field name/values
  • headers - Optional list of column headers

Returns

  • A struct based on the schema with field values

Example

iex> schema = Delimit.Schema.new(MyApp.Person)
iex> schema = Delimit.Schema.add_field(schema, :name, :string)
iex> schema = Delimit.Schema.add_field(schema, :age, :integer)
iex> Delimit.Schema.to_struct(schema, ["John Doe", "42"])
%MyApp.Person{name: "John Doe", age: 42}

type_to_typespec(type)

@spec type_to_typespec(atom() | tuple()) :: Macro.t()

Converts a field type to an Elixir typespec.

This function is used to convert field types to proper Elixir typespecs for use in @type definitions.

Parameters

  • type - The field type or a tuple with more specific type information

Returns

  • An Elixir typespec expression

Example

iex> Delimit.Schema.type_to_typespec(:string)
quote do: String.t()

iex> Delimit.Schema.type_to_typespec({:list, :string})
quote do: [String.t()]