Packages
estructura
1.14.0
1.14.0
1.13.0
1.12.0
1.11.0
1.10.2
1.10.1
1.10.0
1.9.0
1.8.3
1.8.2
1.8.1
1.8.0
1.7.2
1.7.1
1.7.0
1.6.1
1.6.0
1.5.0
1.4.2
1.4.1
1.4.0
1.3.3
1.3.2
1.3.1
1.3.0
1.2.12
1.2.11
1.2.10
1.2.9
1.2.8
1.2.7
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.1
1.1.0
1.0.0
0.6.0
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.2
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.0
0.1.0
Extensions for Elixir structures.
Current section
Files
Jump to
Current section
Files
stuff/estructura.cheatmd
# Estructura Cheatsheet
## Setting up structures
### `use Estructura` or `use Estructura.Nested`
#### Basic structure definition
```elixir
defmodule MyStruct do
use Estructura
defstruct [:field1, :field2]
end
```
#### Nested structure definition with types and validation
```elixir
defmodule User do
use Estructura.Nested
defstruct [
name: "",
address: %{city: "", postal_code: ""}
]
def type(:name), do: Estructura.Nested.Type.String
def validate(:name, value), do: String.length(value) > 0
end
```
### `use Estructura.WIA`
#### With Indifferent Access (atom and binary keys)
```elixir
defmodule Config do
use Estructura.WIA,
fields: [
host: [default: "localhost"],
port: [default: 4000, coerce: true, validate: true]
]
@impl Config.Coercible
def coerce_port(value) when is_integer(value), do: {:ok, value}
def coerce_port(value) when is_binary(value) do
case Integer.parse(value) do
{int, ""} -> {:ok, int}
_ -> {:error, "invalid port"}
end
end
@impl Config.Validatable
def validate_port(port) when port in 1..65535, do: {:ok, port}
def validate_port(_port), do: {:error, "port out of range"}
end
# Access with both atom and binary keys
config = %Config{}
config[:port] #=> 4000
config["port"] #=> 4000
put_in(config, ["port"], "8080") #=> %Config{host: "localhost", port: 8080}
```
## Type System
### Built-in Types
#### Available types for common data structures
```elixir
Estructura.Nested.Type.DateTime
Estructura.Nested.Type.Date
Estructura.Nested.Type.Time
Estructura.Nested.Type.URI
Estructura.Nested.Type.IP
Estructura.Nested.Type.String
Estructura.Nested.Type.UUID
```
### Type Scaffolds
#### Enum Types for predefined values
```elixir
defmodule Status do
use Estructura.Nested.Type.Enum,
elements: [:pending, :active, :completed]
end
```
#### Tag Sets for multiple predefined values
```elixir
defmodule Categories do
use Estructura.Nested.Type.Tags,
elements: [:tech, :art, :science]
end
```
## Validation and Coercion
### `validate/2`
#### Define validation rules for fields
```elixir
def validate(:age, value), do: value >= 0
def validate("address.postal_code", value), do: String.match?(value, ~r/^\d{5}$/)
```
### `coerce/2`
#### Define coercion rules for data transformation
```elixir
def coerce(:temperature, str) when is_binary(str) do
case Float.parse(str) do
{num, ""} -> {:ok, num}
_ -> {:error, "Invalid number"}
end
end
```
## Special Features
### Lazy Values
#### Defer computation until needed
```elixir
defmodule Cache do
use Estructura.Nested
defstruct value: Estructura.Lazy.new(&expensive_computation/1)
end
```
### Flattening
#### Convert nested structures to flat maps
```elixir
# Enable flattening
use Estructura.Nested, flattenable: true
# Usage
Estructura.Flattenable.flatten(struct)
# => %{"name" => "value", "address_city" => "London"}
```
### Property Testing
#### Generate test data automatically
```elixir
property "valid structures are validated" do
check all struct <- MyStruct.__generator__() do
assert {:ok, ^struct} = MyStruct.validate(struct)
end
end
```
## Common Options
- `flattenable: true` - Enable structure flattening
- `jason: true` - Enable JSON encoding
- `transformer: true` - Enable transformation capabilities
- `indifferent: true` - Enable indifferent access (atom and binary keys)
## Version: 1.14.0