# What Are Restrictions?

Restrictions are a way of controlling who can use your command.&#x20;

If you ever used other bot frameworks you will have noticed that commands often have fields like `NSFW` or `OwnerOnly` to control access to commands. While these are useful in some cases, they are of no use in more complicated scenarios, often resulting in you having to write checks yourself.&#x20;

Adam solves this through functions.  A `plugin.RestrictionFunc` is a function that takes in a `state.State` and a `*plugin.Context` and returns an error. If that error is `nil`, the restriction is considered passed, if it's not the restriction is considered failed.

You can set restrictions in your command's meta.

## How Restrictions Work

Just like you can use `&&` and `||` to assert `bool`-type conditions, you can use so-called *comparators* to assert that restrictions pass. The restriction package provides four comparators, the first two being`restriction.All` and `restriction.Any`. These, as the name suggests, require all or at least one restriction given to them to pass, respectively. This gives you a more granular control over who can use your command, and who can't.

If a restriction fails, an error message is generated, stating the requirements for using a command. If both restrictions passed to the following `restriction.Any` fail, an error like the one below will be produced.

```go
import (
    "github.com/diamondburned/arikawa/v2/discord"
    "github.com/mavolin/adam/pkg/impl/restriction"
)

var ensignID discord.RoleID = 1234567890987

restriction.Any(
    restriction.UserPermissions(discord.PermissionAdministrator),
    restriction.All(
        restriction.Roles(ensignID),
        restriction.BotOwner,
    ),
)
```

![](https://2104311490-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MFgPCvFyxW4Cz03Ei5p%2F-MRKk5pEAYpzq7wb6ocg%2F-MRKmarpeP_e_dP-Rji_%2Fimage.png?alt=media\&token=2f2efae1-c6f3-4026-bac2-fba51f5cc170)

### Custom Error Messages

While these auto-generated errors are nice in some scenarios, you might want to use custom error messages to better express what is needed from the user. This can be achieved using the other two comparators `restriction.Allf` and `restriction.Anyf`. Both take in an additional `error` parameter that is returned if the restriction fails.

Inside an `Allf` or `Anyf`, you do not need to use an `Xf` comparator again. `All` and `Any` will produce the same result.&#x20;

```go
import (
    "github.com/diamondburned/arikawa/discord"
    "github.com/mavolin/adam/pkg/impl/restriction"
    "github.com/mavolin/adam/pkg/plugin"
)

var ErrRestriction = plugin.NewRestrictionError("You need to be a moderator or " +
    "have the kick permissions to use this command.")

restriction.Anyf(ErrRestriction,
    restriction.Permissions(discord.PermissionManageGuild),
    restriction.Permissions(discord.Kick),
)
```
