# `GeoGenius.Caches.FileSystem`
[🔗](https://github.com/agoodway/geo_genius/blob/main/lib/geo_genius/caches/file_system.ex#L1)

The shipped `GeoGenius.Cache`: artifacts stored as plain files under one
root directory.

The root is `opts[:cache_dir]`, then `config :geo_genius, :cache_dir`, then
a `geo_genius` directory under the system temp directory. A key becomes a
path by joining its segments onto the root; `path/2` refuses a key whose
segments would resolve outside that root, both by rejecting an invalid
segment before any joining happens and by checking the joined, expanded
path still starts with the expanded root.

# `delete`

```elixir
@spec delete(String.t(), keyword()) :: :ok
```

Removes the file stored under `key`, if any. Removing a missing key is not an error.

# `put`

```elixir
@spec put(String.t(), Path.t(), keyword()) :: {:ok, Path.t()} | {:error, term()}
```

Copies `source_path` into the cache under `key`.

The copy lands at a `.part.<unique>` sibling of the final path first and is
renamed onto the final path only once it is complete, so a copy interrupted
midway never leaves a truncated file for `fetch/2` to report as a hit. The
unique suffix gives every call its own staging file, so two concurrent
`put/3` calls for the same key -- two manifest sources sharing a
`cache_key`, or a parallel runner -- never truncate each other's copy under
them. The source is copied, not moved or renamed: the caller may still need
it after the cache has its own copy. On failure the staging file is removed
before the error is returned, so a copy that fails partway (an out-of-space
disk, for instance) leaves nothing behind in the cache root.

---

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