### Start Application with YAML Config Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/patterns.md Ensure the yaml_elixir application is started and load configuration from a file during application startup. ```elixir defmodule MyApp.Application do use Application @impl true def start(_type, _args) do # Ensure yamerl is started Application.ensure_all_started(:yaml_elixir) # Load configuration case load_config() do {:ok, config} -> children = [ {MyApp.Server, config} ] opts = [strategy: :one_for_one, name: MyApp.Supervisor] Supervisor.start_link(children, opts) {:error, reason} -> {:error, reason} end end defp load_config do YamlElixir.read_from_file("config/app.yml", atoms: true) end end ``` -------------------------------- ### Application Setup for Mix Tasks Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/configuration.md Ensure the YamlElixir application is started before use in mix tasks. ```elixir Application.ensure_all_started(:yaml_elixir) data = YamlElixir.read_from_file("config.yml") ``` -------------------------------- ### YAML Configuration in Flow Style Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/data-transformation.md Example of YAML configuration using flow style for inline collections. ```yaml config: {port: 8080, debug: false} items: [apple, banana, cherry] ``` -------------------------------- ### YAML Configuration in Block Style Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/data-transformation.md Example of YAML configuration using block style for nested structures. ```yaml config: port: 8080 debug: false items: - apple - banana - cherry ``` -------------------------------- ### Ensure YAML Elixir Application Started Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/OVERVIEW.md Before using YAML Elixir, ensure the `:yaml_elixir` application is started, especially when using Mix tasks. This is typically handled automatically but can be explicitly started if needed. ```elixir Application.ensure_all_started(:yaml_elixir) config = YamlElixir.read_from_file!("config.yml") ``` -------------------------------- ### Function Specification for Reading Configuration Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/types.md This example shows a function specification for reading configuration from a file. It defines the expected input types (String.t for path, keyword for options) and the return type ({:ok, map()} or {:error, Exception.t()}). ```elixir @spec read_config(String.t(), keyword()) :: {:ok, map()} | {:error, Exception.t()} def read_config(path, opts \ []) do YamlElixir.read_from_file(path, opts) end ``` -------------------------------- ### YAML Input with Duplicate Keys Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/data-transformation.md A YAML example showing duplicate keys within a map. ```yaml key: first key: second ``` -------------------------------- ### Ensure Application Started in Mix Tasks Source: https://github.com/kamillelonek/yaml-elixir/blob/master/README.md Before using :yaml-elixir in your mix tasks, ensure the application has started. This is a prerequisite for using the library's functionalities within the mix environment. ```elixir Application.ensure_all_started(:yaml_elixir) ``` -------------------------------- ### Type Checking with Dialyzer for Config Loading Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/types.md This example demonstrates how to use Dialyzer for type checking when loading configuration from a file. It specifies the expected return type and handles different outcomes from YamlElixir.read_from_file. ```elixir @spec load_config(Path.t()) :: {:ok, map()} | {:error, Exception.t()} def load_config(path) do case YamlElixir.read_from_file(path) do {:ok, data} when is_map(data) -> {:ok, data} {:ok, _} -> {:error, "Config must be a map"} {:error, error} -> {:error, error} end end ``` -------------------------------- ### Handle FileNotFoundError Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/types.md Example demonstrating how to catch and inspect a YamlElixir.FileNotFoundError when a file cannot be read. ```elixir error = case YamlElixir.read_from_file("missing.yml") do {:error, e} = error -> e end case error do %YamlElixir.FileNotFoundError{message: msg} -> IO.puts(msg) end ``` -------------------------------- ### Parse YAML with atom support Source: https://github.com/kamillelonek/yaml-elixir/blob/master/README.md Enable atom support by passing `atoms: true` to `read_from_string` or `read_from_file` to autodetect keys and values starting with ':'. ```elixir yaml = """ a: a b: 1 c: true d: ~ e: nil :f: :atom " YamlElixir.read_from_string(yaml, atoms: true) {:ok, %{:f => :atom, "a" => "a", "b" => 1, "c" => true, "d" => nil, "e" => "nil"}} ``` -------------------------------- ### Registering KeywordList Node Module Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/api-reference/YamlElixir.Node.KeywordList.md Register the YamlElixir.Node.KeywordList module with yamerl. This setup step is required once before parsing YAML documents that use the keyword_list tag. ```elixir :yamerl_app.set_param(:node_mods, [YamlElixir.Node.KeywordList]) ``` -------------------------------- ### Load YAML Config in Mix Task Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/patterns.md Use YamlElixir within a Mix task to load configuration, ensuring the library is started first. ```elixir defmodule Mix.Tasks.MyApp.Setup do use Mix.Task @impl Mix.Task def run(_args) do Application.ensure_all_started(:yaml_elixir) config = YamlElixir.read_from_file!("config.yml", atoms: true) setup_application(config) end defp setup_application(config) do # Use config... end end ``` -------------------------------- ### Error Handling Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/README.md Provides an example of how to handle potential errors during YAML parsing, such as file not found or invalid YAML syntax, using Elixir's `case` statement. ```APIDOC ## Error Handling ```elixir case YamlElixir.read_from_file("config.yml") do {:ok, config} -> # Process config config {:error, %YamlElixir.FileNotFoundError{message: msg}} -> # File not found Logger.error("Config file missing: #{msg}") default_config() {:error, %YamlElixir.ParsingError{line: line, column: col, message: msg}} -> # Invalid YAML Logger.error("Invalid YAML at #{line}:#{col}: #{msg}") {:error, :invalid_config} end ``` ``` -------------------------------- ### YAML to Elixir with Atom Transformation Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/data-transformation.md Shows how enabling `atoms: true` transforms YAML keys and values starting with a colon into Elixir atoms. Mixed key types (atoms and strings) are preserved. ```yaml :port: 8080 :mode: :production name: John values: :enabled: true :debug: :verbose ``` ```elixir %{ port: 8080, mode: :production, "name" => "John", "values" => %{ enabled: true, debug: :verbose } } ``` -------------------------------- ### Handle ParsingError with Location Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/types.md Example showing how to catch and pattern match on a YamlElixir.ParsingError, extracting specific details like line, column, and type. ```elixir error = case YamlElixir.read_from_string("*invalid") do {:error, e} = error -> e end case error do %ParsingError{line: 1, column: 1, type: :no_matching_anchor, message: msg} -> IO.puts("Anchor error at 1:1: #{msg}") %ParsingError{line: l, column: c} -> IO.puts("Parse error at #{l}:#{c}") %ParsingError{message: msg} -> IO.puts("Parse error: #{msg}") end ``` -------------------------------- ### Handle YAML Parsing Errors Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/README.md Provides an example of robust error handling for YAML parsing operations, distinguishing between file not found errors and general parsing errors. ```elixir case YamlElixir.read_from_file("config.yml") do {:ok, config} -> # Process config config {:error, %YamlElixir.FileNotFoundError{message: msg}} -> # File not found Logger.error("Config file missing: #{msg}") default_config() {:error, %YamlElixir.ParsingError{line: line, column: col, message: msg}} -> # Invalid YAML Logger.error("Invalid YAML at #{line}:#{col}: #{msg}") {:error, :invalid_config} end ``` -------------------------------- ### YAML Parsing with Atom Modifier using ~y Sigil Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/api-reference/YamlElixir.Sigil.md Shows how to use the 'a' modifier with the ~y sigil to enable atom detection for keys and values that start with a colon (:). ```elixir import YamlElixir.Sigil # With atom modifier for atom keys @settings ~y""" :mode: :development :timeout: 30 """a # %{:mode => :development, :timeout => 30} ``` -------------------------------- ### Basic Usage Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/README.md Demonstrates how to parse YAML content from files and strings using YamlElixir, including options for atom keys and exception-based parsing. ```APIDOC ## Basic Usage ### Parse from file ```elixir {:ok, data} = YamlElixir.read_from_file("config.yml") ``` ### Parse from string ```elixir {:ok, data} = YamlElixir.read_from_string("key: value") ``` ### With atoms for ergonomic access ```elixir {:ok, config} = YamlElixir.read_from_file("config.yml", atoms: true) # Access: config.port, config.database.host ``` ### Exception-based (for trusted input) ```elixir data = YamlElixir.read_from_file!("config.yml") ``` ### Sigil syntax (requires import) ```elixir import YamlElixir.Sigil @config ~y""" port: 8080 debug: false """ ``` ``` -------------------------------- ### Load Configuration from File with Error Handling Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/OVERVIEW.md Loads configuration from a YAML file, providing a default configuration if the file is not found, or returning an error for other issues. ```elixir case YamlElixir.read_from_file("config.yml") do {:ok, config} -> {:ok, config} {:error, %FileNotFoundError{}} -> {:ok, default_config()} {:error, error} -> {:error, error.message} end ``` -------------------------------- ### Providing Default Configuration on Error Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/errors.md This pattern gracefully handles `FileNotFoundError` by returning a default configuration instead of failing. Other errors are re-raised, ensuring that unexpected issues are not silently ignored. ```elixir config = case YamlElixir.read_from_file("config.yml") do {:ok, data} -> data {:error, %YamlElixir.FileNotFoundError{}} -> default_config() {:error, error} -> raise error end ``` -------------------------------- ### Basic Configuration Loading Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/patterns.md Loads configuration from 'config.yml'. Falls back to default configuration if the file is not found. Handles other potential errors during file reading. ```Elixir defmodule MyApp.Config do def load do case YamlElixir.read_from_file("config.yml") do {:ok, config} -> {:ok, config} {:error, %YamlElixir.FileNotFoundError{}} -> {:ok, default_config()} {:error, error} -> {:error, error} end end defp default_config do %{ "port" => 8080, "debug" => false, "database" => %{"host" => "localhost", "port" => 5432} } end end ``` ```Elixir {:ok, config} = MyApp.Config.load() port = config["port"] db_host = config["database"]["host"] ``` -------------------------------- ### Exception-Based YAML Loading with Logging Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/patterns.md Load YAML configuration using bang (!) functions and rescue specific YamlElixir errors for logging before re-raising. ```elixir def load_config!(path) do try do YamlElixir.read_from_file!(path, atoms: true) rescue e in YamlElixir.FileNotFoundError -> Logger.error("Config file not found: #{path}") reraise e, __STACKTRACE__ e in YamlElixir.ParsingError -> Logger.error("Invalid YAML at #{e.line}:#{e.column}: #{e.message}") reraise e, __STACKTRACE__ end end ``` -------------------------------- ### YAML Input with Complex Map Keys Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/data-transformation.md Demonstrates YAML syntax where lists and other complex structures are used as map keys. ```yaml ? [a, b] : value1 ? [c, d] : value2 ? key3 : value3 ``` -------------------------------- ### Parse YAML from File and String Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/README.md Demonstrates parsing YAML content from both files and strings. Supports options for atom keys and exception-based parsing for trusted input. ```elixir # Parse from file {:ok, data} = YamlElixir.read_from_file("config.yml") # Parse from string {:ok, data} = YamlElixir.read_from_string("key: value") # With atoms for ergonomic access {:ok, config} = YamlElixir.read_from_file("config.yml", atoms: true) # Access: config.port, config.database.host # Exception-based (for trusted input) data = YamlElixir.read_from_file!("config.yml") # Sigil syntax (requires import) import YamlElixir.Sigil @config ~y""" port: 8080 debug: false """ ``` -------------------------------- ### YAML Input with Empty Structures Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/data-transformation.md Demonstrates YAML input containing empty map, empty list, and blank string. ```yaml empty_map: {} empty_list: [] blank_string: "" ``` -------------------------------- ### Load Valid Config Fixture Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/patterns.md Tests loading a valid YAML configuration file from a fixture. Asserts that the 'port' key has the expected value. Uses ExUnit for testing. ```elixir defmodule MyApp.ConfigTest do use ExUnit.Case test "loads valid config" do path = Path.join(File.cwd!(), "test/fixtures/config_valid.yml") {:ok, config} = YamlElixir.read_from_file(path) assert config["port"] == 8080 end test "handles missing file" do {:error, %YamlElixir.FileNotFoundError{}} = YamlElixir.read_from_file("nonexistent.yml") end test "reports parse errors with location" do yaml = "invalid: [yaml" {:error, error} = YamlElixir.read_from_string(yaml) assert error.line != nil assert error.column != nil end end ``` -------------------------------- ### Load Configuration with Atom Access Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/OVERVIEW.md Loads configuration from a YAML file and enables ergonomic access to map keys as atoms. Use this when you prefer atom-based access over string keys. ```elixir {:ok, config} = YamlElixir.read_from_file("config.yml", atoms: true) # Now access with: config.port instead of config["port"] ``` -------------------------------- ### Enable Atom Detection in YamlElixir Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/configuration.md Use the `atoms: true` option to automatically convert string keys and bareword values starting with a colon to Elixir atoms. Be cautious with untrusted input as atoms are not garbage collected. ```elixir yaml = """ :port: 8080 :mode: :production name: John """ # Without atoms: false {:ok, data} = YamlElixir.read_from_string(yaml) %{ "":port" => 8080, ":mode" => ":production", "name" => "John"} # With atoms: true {:ok, data} = YamlElixir.read_from_string(yaml, atoms: true) %{port: 8080, mode: :production, "name" => "John"} ``` -------------------------------- ### Load YAML Config with Default Values Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/patterns.md Provide default configuration values that are merged with loaded configuration, falling back to defaults if the file is not found. ```elixir def load_config_with_defaults(path, defaults) do case YamlElixir.read_from_file(path) do {:ok, config} -> {:ok, Map.merge(defaults, config)} {:error, %YamlElixir.FileNotFoundError{}} -> {:ok, defaults} {:error, error} -> {:error, error} end end # Usage: defaults = %{"port" => 8080, "debug" => false} {:ok, config} = load_config_with_defaults("config.yml", defaults) ``` -------------------------------- ### Cache Configuration with Cachex Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/patterns.md Caches YAML configuration using Cachex for improved performance. Avoids re-reading and re-parsing the same configuration file multiple times. Requires the Cachex library. ```elixir defmodule Config.Cached do @cache_key :yaml_config def load(path) do case Cachex.get(@cache_key, path) do {:ok, config} when config != nil -> {:ok, config} _ -> case YamlElixir.read_from_file(path, atoms: true) do {:ok, config} -> Cachex.put(@cache_key, path, config) {:ok, config} {:error, error} -> {:error, error} end end end end ``` -------------------------------- ### Environment-Specific Configuration Loading Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/patterns.md Loads configuration from environment-specific files (e.g., 'config/prod.yml'). Falls back to default configuration if the environment-specific file is not found. Handles other potential errors during file reading. ```Elixir defmodule MyApp.Config do def load(env \\ Mix.env()) do file = "config/#{env}.yml" case YamlElixir.read_from_file(file, atoms: true) do {:ok, config} -> {:ok, config} {:error, %YamlElixir.FileNotFoundError{}} -> load_defaults() {:error, error} -> {:error, error} end end defp load_defaults do {:ok, %{port: 8080, debug: true}} end end ``` -------------------------------- ### YAML with Atoms and Merge Anchors Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/data-transformation.md Demonstrates YAML structure using merge anchors for defaults. Requires `atoms: true` and `merge_anchors: true` for Elixir parsing. ```yaml defaults: &defaults :timeout: 30 :retry: 3 app: <<: *defaults :port: 8080 ``` -------------------------------- ### Configure Key and Value Types Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/README.md Illustrates how to configure YamlElixir to use atom keys, convert maps to keyword lists, and resolve YAML merge keys. Also shows parsing JSON. ```elixir # String keys by default {:ok, config} = YamlElixir.read_from_file("config.yml") # %{"port" => 8080} # Atom keys and values starting with : {:ok, config} = YamlElixir.read_from_file("config.yml", atoms: true) # %{port: 8080, mode: :production} # Convert all maps to keyword lists {:ok, config} = YamlElixir.read_from_file("config.yml", maps_as_keywords: true) # [{"port", 8080}] # Resolve YAML merge keys {:ok, config} = YamlElixir.read_from_file("config.yml", merge_anchors: true) # Custom tag processors {:ok, data} = YamlElixir.read_from_file( "config.yml", node_mods: [YamlElixir.Node.KeywordList] ) # Parse JSON {:ok, data} = YamlElixir.read_from_string(json_string, schema: :json) ``` -------------------------------- ### read_from_file! Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/api-reference/YamlElixir.md Parses a YAML file and returns the first document. Raises an exception if the file is not found or contains invalid syntax. ```APIDOC ## read_from_file! Parses a YAML file and returns the first document. Raises exception on error. ### Signature ```elixir read_from_file!(path, options \ []) :: term() | no_return() ``` ### Parameters #### Path Parameters - **path** (string) - required - Absolute or relative file path to YAML file - **options** (keyword()) - optional - Parsing options ### Options Same as `read_from_file/2`. ### Returns Parsed term on success. ### Throws - `YamlElixir.FileNotFoundError` — File does not exist or cannot be opened - `YamlElixir.ParsingError` — Invalid YAML syntax ### Example ```elixir data = YamlElixir.read_from_file!("config.yml") # %{"port" => 8080, "debug" => false} # Raises YamlElixir.FileNotFoundError YamlElixir.read_from_file!("missing.yml") ``` ``` -------------------------------- ### Multi-Document YAML Input File Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/data-transformation.md A YAML file containing multiple documents separated by '---'. ```yaml --- name: doc1 value: 100 --- name: doc2 value: 200 ``` -------------------------------- ### YAML Lists to Elixir Lists Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/data-transformation.md Shows how YAML sequences are transformed into Elixir lists within a map. ```yaml items: - apple - banana - cherry ``` ```elixir %{ "items" => ["apple", "banana", "cherry"] } ``` -------------------------------- ### Simple Success/Failure Handling with Tuples Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/errors.md Use this pattern for basic error checking where you only need to distinguish between a successful parse and any type of error. It returns a tuple indicating success with data or failure with a formatted error message. ```elixir case YamlElixir.read_from_file("config.yml") do {:ok, data} -> {:ok, data} {:error, error} -> {:error, "Failed to parse YAML: #{error.message}"} end ``` -------------------------------- ### Exception-Based Error Handling with Try/Rescue Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/errors.md Employ this pattern when you prefer to handle errors as exceptions. The `try/rescue` block catches specific `YamlElixir` exceptions, allowing for logging and application shutdown or recovery. ```elixir try do config = YamlElixir.read_from_file!("config.yml") setup_application(config) rescue e in YamlElixir.FileNotFoundError -> Logger.error("Missing config file: #{e.message}") shutdown() e in YamlElixir.ParsingError -> Logger.error("Invalid config YAML: #{e.message}") shutdown() end ``` -------------------------------- ### Read Single YAML Document from File Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/api-reference/YamlElixir.md Parses the first YAML document from a specified file. Raises an exception if the file is not found or contains invalid syntax. ```elixir read_from_file!(path, options \ []) :: term() | no_return() ``` ```elixir data = YamlElixir.read_from_file!("config.yml") %{"port" => 8080, "debug" => false} ``` ```elixir # Raises YamlElixir.FileNotFoundError YamlElixir.read_from_file!("missing.yml") ``` -------------------------------- ### Parsing YAML with KeywordList Node Using Options Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/api-reference/YamlElixir.Node.KeywordList.md Reads a YAML file and parses tagged maps as keyword lists by passing the node module directly in the options. This avoids the global registration step. ```elixir data = YamlElixir.read_from_file!("config.yml", node_mods: [YamlElixir.Node.KeywordList]) ``` -------------------------------- ### Main Functions Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/README.md Lists the primary functions available in YamlElixir for reading YAML data, detailing their return types and intended use. ```APIDOC ## Main Functions | Function | Returns | Use For | |---|---|---| | `read_from_file/2` | `{:ok, term}` \| `{:error, exc}` | Parse YAML file (first doc) | | `read_from_file!/2` | `term` \| raises | Parse file, raise on error | | `read_all_from_file/2` | `{:ok, [term]}` \| `{:error, exc}` | Parse all docs in file | | `read_all_from_file!/2` | `[term]` \| raises | Parse all docs, raise on error | | `read_from_string/2` | `{:ok, term}` \| `{:error, exc}` | Parse YAML string (first doc) | | `read_from_string!/2` | `term` \| raises | Parse string, raise on error | | `read_all_from_string/2` | `{:ok, [term]}` \| `{:error, exc}` | Parse all docs in string | | `read_all_from_string!/2` | `[term]` \| raises | Parse all docs, raise on error | ``` -------------------------------- ### Read YAML with Atoms and Anchors Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/configuration.md Use this to read YAML files while preserving atoms and merging anchor definitions. ```elixir {:ok, config} = YamlElixir.read_from_file( "config.yml", atoms: true, merge_anchors: true ) ``` -------------------------------- ### Pretty-Print YAML Configuration Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/patterns.md Use this function to read a YAML file and pretty-print its content to the console for debugging. It handles both successful reads and errors. ```elixir def debug_config(path) do case YamlElixir.read_from_file(path) do {:ok, config} -> IO.inspect(config, pretty: true, limit: :infinity) {:ok, config} {:error, error} -> IO.inspect(error, label: "Error") {:error, error} end end ``` -------------------------------- ### Parse YAML with Sigil in Tests Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/patterns.md Demonstrates parsing YAML directly within tests using the `~y` sigil. Useful for defining expected YAML structures inline. Requires importing YamlElixir.Sigil. ```elixir defmodule MyApp.DataTest do use ExUnit.Case import YamlElixir.Sigil test "parses expected data" do expected = ~y""" id: 1 name: Test tags: - a - b """ assert expected == %{ "id" => 1, "name" => "Test", "tags" => ["a", "b"] } end end ``` -------------------------------- ### Basic YAML Parsing with ~y Sigil Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/api-reference/YamlElixir.Sigil.md Demonstrates basic inline YAML parsing without atom modifiers. The parsed content is returned as a map. ```elixir import YamlElixir.Sigil # Basic usage without atoms @config ~y""" debug: false port: 8080 """ # %{"debug" => false, "port" => 8080} ``` ```elixir import YamlElixir.Sigil # Inline YAML result = ~y"name: John age: 30" # %{"name" => "John", "age" => 30} ``` -------------------------------- ### read_all_from_file! Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/api-reference/YamlElixir.md Parses all YAML documents in a file. Raises an exception on error. It takes a file path and optional parsing options, returning a list of parsed documents. ```APIDOC ## read_all_from_file! Parses all YAML documents in a file. Raises exception on error. ### Function Signature ```elixir read_all_from_file!(path, options \ []) :: [term()] | no_return() ``` ### Parameters #### Path Parameters - **path** (string) - Required - Absolute or relative file path to YAML file #### Query Parameters - **options** (keyword()) - Optional - Parsing options. Same as `read_from_file/2`. ### Returns List of parsed documents. ### Throws - `YamlElixir.FileNotFoundError` — File does not exist - `YamlElixir.ParsingError` — Invalid YAML syntax ### Example ```elixir [doc1, doc2] = YamlElixir.read_all_from_file!("multi.yml") # [%{"a" => 1}, %{"b" => 2}] ``` ``` -------------------------------- ### Parsing Options Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/OVERVIEW.md Details the available options for configuring YAML parsing behavior, such as atom conversion, map representation, and merge key resolution. ```APIDOC ## Parsing Options All read functions accept these options: | Option | Type | Default | Purpose | |---|---|---|---| | `atoms` | boolean | false | Convert `:key` to atoms | | `maps_as_keywords` | boolean | false | Convert all maps to keyword lists | | `merge_anchors` | boolean | false | Resolve YAML merge keys | | `node_mods` | [atom] | [] | Custom tag processors | | `schema` | atom | — | Parsing schema (e.g. `:json`) | See [Configuration Options](configuration.md) for detailed descriptions. ``` -------------------------------- ### Read YAML with Minimal Allocation Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/configuration.md Read YAML files with minimal allocation, ensuring all keys and bareword values are treated as strings. ```elixir {:ok, data} = YamlElixir.read_from_file("input.yml") # All keys and bareword values remain as strings ``` -------------------------------- ### YamlElixir Parse Options Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/types.md Parse options are passed as keyword lists with specific key/value pairs. Refer to Configuration Options for detailed descriptions. ```elixir options :: [ atoms: boolean(), maps_as_keywords: boolean(), merge_anchors: boolean(), node_mods: [atom()], schema: atom(), keep_duplicate_keys: boolean(), detailed_constr: boolean(), str_node_as_binary: boolean() ] ``` -------------------------------- ### Common Options Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/README.md Explains various options that can be passed to YamlElixir parsing functions to customize behavior, such as key types, map conversion, and anchor merging. ```APIDOC ## Common Options ### String keys by default ```elixir {:ok, config} = YamlElixir.read_from_file("config.yml") # %{"port" => 8080} ``` ### Atom keys and values starting with : ```elixir {:ok, config} = YamlElixir.read_from_file("config.yml", atoms: true) # %{port: 8080, mode: :production} ``` ### Convert all maps to keyword lists ```elixir {:ok, config} = YamlElixir.read_from_file("config.yml", maps_as_keywords: true) # [{"port", 8080}] ``` ### Resolve YAML merge keys ```elixir {:ok, config} = YamlElixir.read_from_file("config.yml", merge_anchors: true) ``` ### Custom tag processors ```elixir {:ok, data} = YamlElixir.read_from_file( "config.yml", node_mods: [YamlElixir.Node.KeywordList] ) ``` ### Parse JSON ```elixir {:ok, data} = YamlElixir.read_from_string(json_string, schema: :json) ``` ``` -------------------------------- ### Parse YAML from a file Source: https://github.com/kamillelonek/yaml-elixir/blob/master/README.md Use YamlElixir.read_from_file/1 to parse a YAML file into an Elixir map. ```elixir path = Path.join(File.cwd!(), "test/fixtures/flat.yml") YamlElixir.read_from_file(path) {:ok, %{"a" => "a", "b" => 1, "c" => true, "d" => nil, "e" => []}} ``` -------------------------------- ### YAML Keyword List Tag Format Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/api-reference/YamlElixir.Node.KeywordList.md Illustrates the correct YAML syntax for applying the `tag:yaml_elixir,2019:keyword_list` tag to a map, ensuring it is parsed as a keyword list. ```yaml my_section: ! key1: value1 key2: value2 ``` -------------------------------- ### Read YAML as Keyword Lists Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/configuration.md Configure YamlElixir to interpret YAML structures as Elixir keyword lists. Ensure the :yamerl_app is set up to use KeywordList nodes. ```elixir :yamerl_app.set_param(:node_mods, [YamlElixir.Node.KeywordList]) {:ok, data} = YamlElixir.read_from_file( "tagged.yml", maps_as_keywords: true ) ``` -------------------------------- ### Parse YAML String (Raise Error) Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/api-reference/YamlElixir.md Parses a YAML string and returns the first document. Use this when you expect valid YAML and want an error to be raised immediately on invalid syntax. ```elixir read_from_string!(string, options \ []) :: term() | no_return() ``` ```elixir data = YamlElixir.read_from_string!("name: John age: 30") %{"name" => "John", "age" => 30} ``` ```elixir YamlElixir.read_from_string!("*invalid") # Raises YamlElixir.ParsingError with message about anchor ``` -------------------------------- ### Lazy Load Configuration with Agent Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/patterns.md Loads YAML configuration lazily using Elixir's Agent. Useful for configurations that are not immediately needed. Requires the Agent module. ```elixir defmodule Config.Lazy do def load(path) do Agent.start_link(fn -> case YamlElixir.read_from_file(path, atoms: true) do {:ok, config} -> config {:error, error} -> raise error end end) end def get(agent, key) do Agent.get(agent, &Map.get(&1, key)) end end # Usage: {:ok, agent} = Config.Lazy.load("config.yml") port = Config.Lazy.get(agent, :port) ``` -------------------------------- ### YAML Mixed Nested Structures to Elixir Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/data-transformation.md Demonstrates the transformation of YAML structures containing both lists and maps into corresponding Elixir nested lists and maps. ```yaml services: - name: api port: 8080 - name: web port: 3000 ``` ```elixir %{ "services" => [ %{"name" => "api", "port" => 8080}, %{"name" => "web", "port" => 3000} ] } ``` -------------------------------- ### Parse YAML with Post-Processing and Validation Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/patterns.md Load YAML from a file, validate its structure, and then process it. This pattern ensures data integrity before further use. ```elixir def load_manifest(path) do with {:ok, data} <- YamlElixir.read_from_file(path, atoms: true), :ok <- validate_manifest(data), {:ok, processed} <- process_manifest(data) do {:ok, processed} end end defp validate_manifest(manifest) do required = [:name, :version] case Enum.find(required, &(not Map.has_key?(manifest, &1))) do nil -> :ok missing -> {:error, "Missing required field: #{missing}"} end end defp process_manifest(manifest) do {:ok, %{ name: manifest.name, version: manifest.version, dependencies: manifest.dependencies || [], scripts: process_scripts(manifest.scripts) }} end defp process_scripts(scripts) when is_map(scripts) do Map.new(scripts, fn {name, cmd} -> {String.to_atom(name), String.trim(cmd)} end) end defp process_scripts(_), do: %{} ``` -------------------------------- ### read_from_string! Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/api-reference/YamlElixir.md Parses a YAML string and returns the first document. Raises an exception on error. ```APIDOC ## read_from_string! Parses a YAML string and returns the first document. Raises exception on error. ```elixir read_from_string!(string, options \ []) :: term() | no_return() ``` ### Parameters #### Path Parameters - **string** (binary()) - required - YAML string content - **options** (keyword()) - optional - Parsing options ### Options Same as `read_from_file/2`. ### Returns Parsed term on success. ### Throws `YamlElixir.ParsingError` — Invalid YAML syntax ### Example ```elixir data = YamlElixir.read_from_string!("name: John\nage: 30") # %{"name" => "John", "age" => 30} YamlElixir.read_from_string!("*invalid") # Raises YamlElixir.ParsingError with message about anchor ``` ``` -------------------------------- ### YAML Input with Large Numbers Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/data-transformation.md Demonstrates YAML input with a large integer and a number in scientific notation. ```yaml big_int: 9223372036854775807 scientific: 1.23e10 ``` -------------------------------- ### Parse All YAML Documents from String (Raise Error) Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/api-reference/YamlElixir.md Parses all YAML documents from a string and returns them as a list. Use this when you expect valid YAML and want an error to be raised immediately on invalid syntax. ```elixir read_all_from_string!(string, options \ []) :: [term()] | no_return() ``` ```elixir [doc1, doc2] = YamlElixir.read_all_from_string!("---\na: 1 --- b: 2") [%{"a" => 1}, %{"b" => 2}] ``` -------------------------------- ### Parse All YAML Documents from a File Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/api-reference/YamlElixir.md Use `read_all_from_file!` to parse all YAML documents from a specified file. It raises an exception if the file is not found or contains invalid syntax. Accepts optional parsing options. ```elixir read_all_from_file!(path, options \ []) :: [term()] | no_return() ``` ```elixir [doc1, doc2] = YamlElixir.read_all_from_file!("multi.yml") [%{"a" => 1}, %{"b" => 2}] ``` -------------------------------- ### YAML with Maps as Keywords and Atoms Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/data-transformation.md YAML structure representing different environments with keyword-like maps. Requires `atoms: true` and `maps_as_keywords: true` for Elixir parsing. ```yaml :prod: :db: :postgresql :host: localhost :dev: :db: :sqlite ``` -------------------------------- ### YAML Input with keyword_list Tag Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/data-transformation.md Demonstrates a YAML input with a custom tag '!' which is transformed into a keyword list in Elixir. Untagged blocks remain maps. ```yaml config: ! foo: bar baz: qux regular_map: foo: bar baz: qux ``` -------------------------------- ### Read YAML from File Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/api-reference/YamlElixir.md Parses a YAML file and returns the first document. Use this function for safe parsing that returns an error tuple on failure. It accepts a file path and optional parsing configurations. ```elixir read_from_file(path, options \\ []) :: {:ok, term()} | {:error, YamlElixir.FileNotFoundError | YamlElixir.ParsingError} ``` ```elixir {:ok, data} = YamlElixir.read_from_file("config.yml") # {:ok, %{"port" => 8080, "debug" => false}} ``` ```elixir {:ok, data} = YamlElixir.read_from_file("config.yml", atoms: true) # {:ok, %{"port" => 8080, "debug" => false}} ``` ```elixir {:error, error} = YamlElixir.read_from_file("missing.yml") # {:error, %YamlElixir.FileNotFoundError{message: "Failed to open file..."}} ``` -------------------------------- ### Read YAML from Environment Variable String Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/configuration.md Load YAML content directly from an environment variable into an Elixir configuration. ```elixir yaml_string = System.get_env("APP_CONFIG") {:ok, config} = YamlElixir.read_from_string(yaml_string) ``` -------------------------------- ### YAML Input with Quoted and Unquoted Strings Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/data-transformation.md Shows YAML strings with and without quotes, including a number as a string and a string with a colon. ```yaml unquoted: hello quoted: "hello" number_string: "123" colon_string: ":not_an_atom" ``` -------------------------------- ### Inline YAML with Atoms for Module Attributes Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/patterns.md Embed YAML with atom keys using the ~y sigil and assign them to module attributes. This allows direct access to configuration values as atoms. ```elixir defmodule MyApp.Settings do import YamlElixir.Sigil @env ~y""" :mode: :production :timeout: 30 :retries: 3 """a def environment, do: @env end # Usage: env = MyApp.Settings.environment() IO.inspect(env.mode) # :production ``` -------------------------------- ### read_all_from_string! Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/api-reference/YamlElixir.md Parses all YAML documents in a string and returns them as a list. Raises an exception on error. ```APIDOC ## read_all_from_string! Parses all YAML documents in a string. Raises exception on error. ```elixir read_all_from_string!(string, options \ []) :: [term()] | no_return() ``` ### Parameters #### Path Parameters - **string** (binary()) - required - YAML string content - **options** (keyword()) - optional - Parsing options ### Options Same as `read_from_file/2`. ### Returns List of parsed documents. ### Throws `YamlElixir.ParsingError` — Invalid YAML syntax ### Example ```elixir [doc1, doc2] = YamlElixir.read_all_from_string!("---\na: 1\n---\nb: 2") # [%{"a" => 1}, %{"b" => 2}] ``` -------------------------------- ### Add yaml_elixir to mix.exs Source: https://github.com/kamillelonek/yaml-elixir/blob/master/README.md Add the :yaml_elixir dependency to your project's mix.exs file and run 'mix deps.get'. ```elixir defp deps do [ # ... {:yaml_elixir, "~> x.x"}, ] end ``` -------------------------------- ### Parse and Transform YAML in One Step Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/patterns.md Read YAML from a file and apply a custom transformation function in a single step. This is useful for validating and restructuring data upon loading. ```elixir def load_and_transform(path) do case YamlElixir.read_from_file(path, atoms: true) do {:ok, config} -> {:ok, transform_config(config)} {:error, error} -> {:error, error} end end defp transform_config(config) do # Example: Convert nested string keys to atoms %{ port: config.port, debug: config.debug, database: %{ host: config.database.host, port: config.database.port, pool_size: config.database.pool_size || 10 } } end ``` -------------------------------- ### Parse All YAML Documents from String (Return Result) Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/api-reference/YamlElixir.md Parses all YAML documents from a string, supporting multi-document strings. Returns a tuple indicating success with a list of documents or an error tuple. ```elixir read_all_from_string(string, options \ []) :: {:ok, [term()]} | {:error, YamlElixir.ParsingError} ``` ```elixir yaml = "---\na: 1 --- b: 2" {:ok, docs} = YamlElixir.read_all_from_string(yaml) # {:ok, [%{"a" => 1}, %{"b" => 2}]} ``` -------------------------------- ### Selective vs. Global Map Conversion in Yamerl Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/api-reference/YamlElixir.Node.KeywordList.md Compares the selective parsing of tagged maps as keyword lists using `YamlElixir.Node.KeywordList` with the global `maps_as_keywords: true` option. ```elixir # Convert all maps: data = YamlElixir.read_from_file("file.yml", maps_as_keywords: true) # Convert only tagged maps: :yamerl_app.set_param(:node_mods, [YamlElixir.Node.KeywordList]) data = YamlElixir.read_from_file("file.yml", node_mods: [YamlElixir.Node.KeywordList]) ``` -------------------------------- ### Read YAML Data from File Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/OVERVIEW.md Use `YamlElixir.read_from_file!` to parse a YAML file and access its data. Ensure the file exists and is valid YAML. ```elixir data = YamlElixir.read_from_file!("config.yml") port = data["port"] ``` -------------------------------- ### YAML Scalars to Elixir Types Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/data-transformation.md Demonstrates the default conversion of YAML scalar types (string, integer, float, boolean, null) to their corresponding Elixir representations. ```yaml string: hello integer: 42 float: 3.14 boolean_true: true boolean_false: false null_value: ~ null_alternative: null ``` ```elixir %{ "string" => "hello", "integer" => 42, "float" => 3.14, "boolean_true" => true, "boolean_false" => false, "null_value" => nil, "null_alternative" => nil } ``` -------------------------------- ### Read All YAML Documents from File Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/api-reference/YamlElixir.md Parses all YAML documents from a file, supporting multi-document files. Returns a tuple with :ok and a list of documents on success, or :error and an exception on failure. ```elixir read_all_from_file(path, options \ []) :: {:ok, [term()]} | {:error, YamlElixir.FileNotFoundError | YamlElixir.ParsingError} ``` ```elixir # File contains: --- a: 1 --- b: 2 {:ok, [doc1, doc2]} = YamlElixir.read_all_from_file("multi.yml") # {:ok, [%{"a" => 1}, %{"b" => 2}]} ``` -------------------------------- ### YAML Nested Maps to Elixir Nested Maps Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/data-transformation.md Illustrates the default transformation of nested YAML maps into nested Elixir maps. ```yaml database: host: localhost port: 5432 credentials: user: admin pass: secret ``` ```elixir %{ "database" => %{ "host" => "localhost", "port" => 5432, "credentials" => %{ "user" => "admin", "pass" => "secret" } } } ``` -------------------------------- ### Elixir Output from JSON Input Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/data-transformation.md The Elixir representation of the JSON input, demonstrating how JSON data types are mapped to Elixir equivalents. ```elixir %{ "name" => "John", "age" => 30, "active" => true, "email" => nil } ``` -------------------------------- ### Basic YAML to Elixir Keyword List Parsing Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/api-reference/YamlElixir.Node.KeywordList.md Parses a YAML file where a specific map is tagged with `!` into an Elixir keyword list. Ensure the node module is registered first. ```elixir :yamerl_app.set_param(:node_mods, [YamlElixir.Node.KeywordList]) {:ok, data} = YamlElixir.read_from_file("config.yml") # %{"prod" => %{"config" => [{"foo", "bar"}, {"bar", "baz"}]}} ``` -------------------------------- ### Configure yamerl for Erlang atoms Source: https://github.com/kamillelonek/yaml-elixir/blob/master/README.md Alternatively, configure yamerl to use Erlang atoms directly by setting node modules. ```elixir :yamerl_app.set_param(:node_mods, [:yamerl_node_erlang_atom]) ``` -------------------------------- ### Load All Documents from a Multi-Document File Source: https://github.com/kamillelonek/yaml-elixir/blob/master/_autodocs/OVERVIEW.md Reads all YAML documents from a single file, returning them as a list. Useful for files containing multiple distinct YAML structures. ```elixir {:ok, [doc1, doc2, doc3]} = YamlElixir.read_all_from_file("multi.yml") ```