# `Pact.Patterns`

A module for creating JSON and string patterns for Pact testing.

JSON patterns can include various data types and matchers, while string patterns
are limited to strings and specific matchers.

# `json_matcher`

```elixir
@type json_matcher() ::
  {:matching_regex, %{regex: String.t(), example: String.t()}}
  | {:like, json_pattern()}
  | {:each_like, %{json_pattern: json_pattern(), min_len: non_neg_integer()}}
  | {:date_time, %{format: String.t(), example: String.t()}}
```

# `json_pattern`

```elixir
@type json_pattern() ::
  integer()
  | float()
  | boolean()
  | nil
  | binary()
  | atom()
  | [json_pattern()]
  | %{optional(atom() | binary()) =&gt; json_pattern()}
  | json_matcher()
```

# `string_matcher`

```elixir
@type string_matcher() ::
  {:matching_regex, %{regex: String.t(), example: String.t()}}
  | {:like, string_pattern()}
  | {:date_time, %{format: String.t(), example: String.t()}}
```

# `string_pattern`

```elixir
@type string_pattern() :: binary() | string_matcher()
```

# `datetime`

```elixir
@spec datetime(String.t(), String.t()) :: json_matcher() | string_matcher()
```

Creates a datetime matcher for both JSON and string patterns.

## Examples

    iex> Pact.Patterns.datetime("yyyy-MM-dd", "2000-01-01")
    {:date_time, %{format: "yyyy-MM-dd", example: "2000-01-01"}}

# `each_like`

```elixir
@spec each_like(json_pattern(), non_neg_integer()) :: json_matcher()
```

Creates an each_like matcher for JSON arrays with optional minimum length.

## Parameters
  - pattern: The example pattern for array elements
  - min_len: Minimum required array length (default: 1, must be ≥ 0)

## Examples
    # With default minimum length
    iex> Pact.Patterns.each_like("item")
    {:each_like, %{json_pattern: "item", min_len: 1}}

    # With explicit minimum length
    iex> Pact.Patterns.each_like("item", 3)
    {:each_like, %{json_pattern: "item", min_len: 3}}

# `json_pattern`

```elixir
@spec json_pattern(json_pattern()) :: json_pattern()
```

Builds a JSON pattern structure.

## Examples

    iex> Pact.Patterns.json_pattern(%{"age" => Pact.Patterns.like(25)})
    %{"age" => {:like, 25}}

# `like`

```elixir
@spec like(json_pattern()) :: json_matcher()
```

Creates a like matcher for JSON patterns. When used in string patterns, the inner
pattern must be a valid string pattern.

## Examples

    iex> Pact.Patterns.like(42)
    {:like, 42}

# `matching_regex`

```elixir
@spec matching_regex(String.t(), String.t()) :: json_matcher() | string_matcher()
```

Creates a regex matcher for both JSON and string patterns.

## Examples

    iex> Pact.Patterns.matching_regex("^\d+$", "123")
    {:matching_regex, %{regex: "^\d+$", example: "123"}}

# `string_pattern`

```elixir
@spec string_pattern(string_pattern()) :: string_pattern()
```

Builds a string pattern structure.

## Examples

    iex> Pact.Patterns.string_pattern(Pact.Patterns.like("example"))
    {:like, "example"}

# `term`

```elixir
@spec term(String.t(), String.t()) :: json_matcher() | string_matcher()
```

Creates a regex matcher (alias for matching_regex/2).

## Examples

    iex> Pact.Patterns.term("^\d+$", "123")
    {:matching_regex, %{regex: "^\d+$", example: "123"}}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
