97 lines
3.5 KiB
Markdown
97 lines
3.5 KiB
Markdown
# Community Garden
|
|
|
|
Welcome to Community Garden on Exercism's Elixir Track.
|
|
If you need help running the tests or submitting your code, check out `HELP.md`.
|
|
If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :)
|
|
|
|
## Introduction
|
|
|
|
## Agent
|
|
|
|
The `Agent` module facilitates an abstraction for spawning [processes and the _receive-send_ loop][exercism-processes]. From here, we will call processes started using the `Agent` module _'agent processes'_. An _agent process_ might be chosen to represent a central shared state.
|
|
|
|
To start an _agent process_, `Agent` provides the `start/2` function. The supplied function when `start`_-ing_ the _agent process_ returns the initial state of the process:
|
|
|
|
```elixir
|
|
# Start an agent process with an initial value of an empty list
|
|
{:ok, agent_pid} = Agent.start(fn -> [] end)
|
|
```
|
|
|
|
Just like `Map` or `List`, `Agent` provides many functions for working with _agent processes_.
|
|
|
|
It is customary to organize and encapsulate all `Agent`-related functionality into a module for the domain being modeled.
|
|
|
|
[exercism-processes]: https://exercism.org/tracks/elixir/concepts/processes
|
|
|
|
## Instructions
|
|
|
|
Your community association has asked you to implement a simple registry application to manage the community garden registrations. The `Plot` struct has already been provided for you.
|
|
|
|
## 1. Open the garden
|
|
|
|
Implement the `CommunityGarden.start/1` function, it should receive an optional keyword list of options to pass forward to the _agent process_. The garden's initial state should be initialized to represent an empty collection of plots. It should return an `:ok` tuple with the garden's pid.
|
|
|
|
```elixir
|
|
{:ok, pid} = CommunityGarden.start()
|
|
# => {:ok, #PID<0.112.0>}
|
|
```
|
|
|
|
## 2. List the registrations
|
|
|
|
Implement the `CommunityGarden.list_registrations/1` function. It should receive the `pid` for the community garden. It should return a list of the stored plots that are registered.
|
|
|
|
```elixir
|
|
CommunityGarden.list_registrations(pid)
|
|
# => []
|
|
```
|
|
|
|
> At this point, we haven't added the ability to register a plot, so this list should be empty
|
|
|
|
## 3. Register plots to a person
|
|
|
|
Implement the `CommunityGarden.register/2` function. It should receive the `pid` for the community garden and a name to register the plot. It should return the `Plot` struct with the plot's id and person registered to when it is successful.
|
|
|
|
The ids should be incremental and unique. You can keep an id counter in the agent's state.
|
|
|
|
```elixir
|
|
CommunityGarden.register(pid, "Emma Balan")
|
|
# => %Plot{plot_id: 1, registered_to: "Emma Balan"}
|
|
CommunityGarden.list_registrations(pid)
|
|
# => [%Plot{plot_id: 1, registered_to: "Emma Balan"}]
|
|
```
|
|
|
|
## 4. Release plots
|
|
|
|
Implement the `CommunityGarden.release/2` function. It should receive the `pid` and `id` of the plot to be released. It should return `:ok` on success. When a plot is released, the id is not re-used, it is used as a unique identifier only.
|
|
|
|
```elixir
|
|
CommunityGarden.release(pid, 1)
|
|
# => :ok
|
|
CommunityGarden.list_registrations(pid)
|
|
# => []
|
|
```
|
|
|
|
## 5. Get a registered plot
|
|
|
|
Implement the `CommunityGarden.get_registration/2` function. It should receive the `pid` and `id` of the plot to be checked. It should return the plot if it is registered, and `:not_found` if it is unregistered.
|
|
|
|
```elixir
|
|
CommunityGarden.get_registration(pid, 1)
|
|
# => %Plot{plot_id: 1, registered_to: "Emma Balan"}
|
|
CommunityGarden.get_registration(pid, 7)
|
|
# => {:not_found, "plot is unregistered"}
|
|
```
|
|
|
|
## Source
|
|
|
|
### Created by
|
|
|
|
- @neenjaw
|
|
|
|
### Contributed to by
|
|
|
|
- @angelikatyborska
|
|
- @jrr
|
|
- @efx
|
|
- @justin-m-morgan
|
|
- @cr0t |