# `locus_custom_fetcher`
[🔗](https://github.com/g-andrade/locus/blob/2.3.15/src/locus_custom_fetcher.erl#L24)

Callbacks for providing your own database fetcher.

# `description`

```erlang
-type description() :: #{database_is_stored_remotely := boolean(), database_is_fetched_from := term()}.
```

# `event`

```erlang
-type event() :: event_load_attempt_started() | event_load_attempt_dismissed().
```

# `event_load_attempt_dismissed`

```erlang
-type event_load_attempt_dismissed() :: {load_attempt_dismissed, source()}.
```

# `event_load_attempt_started`

```erlang
-type event_load_attempt_started() :: {load_attempt_started, source()}.
```

# `msg`

```erlang
-type msg() ::
          {event, event()} |
          {finished, {success, success()}} |
          {finished, dismissed} |
          {finished, {error, term()}}.
```

# `source`

```erlang
-type source() :: {local | remote, {custom, term()}}.
```

# `state`

```erlang
-opaque state()
```

# `success`

```erlang
-type success() ::
          #{format := locus_loader:blob_format(),
            content := binary(),
            metadata := successful_fetch_metadata()}.
```

# `successful_fetch_metadata`

```erlang
-type successful_fetch_metadata() ::
          #{fetched_from := term(), modified_on := calendar:datetime() | unknown}.
```

# `conditionally_fetch`

```erlang
-callback conditionally_fetch(Args, {depending_on, PreviousFetchMetadata}) ->
                                 {fetched, Success} | dismissed | {error, Reason}
                                 when
                                     Args :: term(),
                                     PreviousFetchMetadata :: successful_fetch_metadata(),
                                     Success :: success(),
                                     Reason :: term().
```

# `description`

```erlang
-callback description(Args) -> description() when Args :: term().
```

# `fetch`

```erlang
-callback fetch(Args) -> {fetched, Success} | {error, Reason}
                   when Args :: term(), Success :: success(), Reason :: term().
```

# `code_change`

```erlang
-spec code_change(term(), state(), term()) -> {ok, state()}.
```

# `description`

```erlang
-spec description(module(), term()) -> description().
```

# `handle_call`

```erlang
-spec handle_call(term(), {pid(), reference()}, state()) -> {stop, unexpected_call, state()}.
```

# `handle_cast`

```erlang
-spec handle_cast(term(), state()) -> {stop, unexpected_cast, state()}.
```

# `handle_continue`

```erlang
-spec handle_continue(fetch, state()) -> {stop, normal, state()}.
```

# `handle_info`

```erlang
-spec handle_info(term(), state()) -> {stop, unexpected_info, state()}.
```

# `init`

```erlang
-spec init([InitArg, ...]) -> {ok, state(), {continue, fetch}}
              when
                  InitArg :: OwnerPid | Source | Module | Args | PreviousFetchMetadata,
                  OwnerPid :: pid(),
                  Source :: source(),
                  Module :: module(),
                  Args :: term(),
                  PreviousFetchMetadata :: successful_fetch_metadata() | undefined.
```

# `source`

```erlang
-spec source(module(), term()) -> source().
```

# `start_link`

```erlang
-spec start_link(source(), module(), term(), successful_fetch_metadata() | undefined) -> {ok, pid()}.
```

# `terminate`

```erlang
-spec terminate(term(), state()) -> ok.
```

---

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