> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sageprotocol.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Moderation

> Manages moderator and owner roles, permissions, and moderator state tracking.

```rust theme={null}
use sui::table;
```

<Tip>
  Explore this module further in the Mover Registry: @sage/shared
</Tip>

## Structs

### `Moderation`

Table of `User`s authorized to take moderator actions on a forum.

```rust theme={null}
public struct Moderation has store
```

<Expandable title="Fields">
  ```rust theme={null}
    moderation: sui::table::Table<address, u8>
  ```
</Expandable>

## Constants

Represents that the moderator is the owner.

```rust theme={null}
const OWNER: u8 = 0;
```

Represents that the moderator has the lowest permissions.

```rust theme={null}
const MODERATOR: u8 = 1;
```

Represents that a moderator was added.

```rust theme={null}
const MODERATOR_ADD: u8 = 10;
```

Represents that a moderator was removed.

```rust theme={null}
const MODERATOR_REMOVE: u8 = 11;
```

Error code used when a moderator tries to remove the owner.

```rust theme={null}
const EIsOwner: u64 = 370;
```

Error code used when a non-moderator attempts a moderator action.

```rust theme={null}
const EIsNotModerator: u64 = 371;
```

Error code used when a non-owner attempts an owner action.

```rust theme={null}
const EIsNotOwner: u64 = 372;
```

## Functions

### `assert_is_moderator`

Aborts with `EIsNotModerator` if the user is not a moderator or owner.

```rust theme={null}
public fun assert_is_moderator(moderation: &Moderation, user: address)
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun assert_is_moderator(
        moderation: &Moderation,
        user: address
    ) {
        let is_moderator = is_moderator(
            moderation,
            user
        );

        assert!(is_moderator, EIsNotModerator);
    }
  ```
</Expandable>

### `assert_is_owner`

Aborts with `EIsNotOwner` if the user is not the owner.

```rust theme={null}
public fun assert_is_owner(moderation: &Moderation, user: address)
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun assert_is_owner(
        moderation: &Moderation,
        user: address
    ) {
        let is_owner = is_owner(
            moderation,
            user
        );

        assert!(is_owner, EIsNotOwner);
    }
  ```
</Expandable>

### `create`

Creates a new `Moderation` instance.

```rust theme={null}
public fun create(ctx: &mut TxContext): (Moderation, u8, u8)
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun create(
        ctx: &mut TxContext
    ): (Moderation, u8, u8) {
        let self = tx_context::sender(ctx);

        let mut moderation = Moderation {
            moderation: table::new(ctx)
        };

        let (event, message) = make_owner(
            &mut moderation,
            self
        );

        (moderation, event, message)
    }
  ```
</Expandable>

### `get_length`

Get number of moderators and owners.

```rust theme={null}
public fun get_length(moderation: &Moderation): u64
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun get_length(
        moderation: &Moderation
    ): u64 {
        moderation.moderation.length()
    }
  ```
</Expandable>

### `is_moderator`

Returns true or false based on whether the address is a moderator.

```rust theme={null}
public fun is_moderator(moderation: &Moderation, user: address): bool
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun is_moderator(
        moderation: &Moderation,
        user: address
    ): bool {
        moderation.moderation.contains(user)
    }
  ```
</Expandable>

### `is_owner`

Returns true or false based on whether the address is the owner.

```rust theme={null}
public fun is_owner(moderation: &Moderation, user: address): bool
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun is_owner(
        moderation: &Moderation,
        user: address
    ): bool {
        let is_moderator = is_moderator(
            moderation,
            user
        );

        if (!is_moderator) {
            false
        } else {
            moderation.moderation[user] == OWNER
        }
    }
  ```
</Expandable>

### `make_moderator`

Adds the address as a moderator.

```rust theme={null}
public fun make_moderator(moderation: &mut Moderation, user: address): (u8, u8)
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun make_moderator(
        moderation: &mut Moderation,
        user: address
    ): (u8, u8) {
        moderation.moderation.add(
            user,
            MODERATOR
        );

        (MODERATOR_ADD, MODERATOR)
    }
  ```
</Expandable>

### `make_owner`

Adds the address as the owner.

```rust theme={null}
public fun make_owner(moderation: &mut Moderation, user: address): (u8, u8)
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun make_owner(
        moderation: &mut Moderation,
        user: address
    ): (u8, u8) {
        moderation.moderation.add(
            user,
            OWNER
        );

        (MODERATOR_ADD, OWNER)
    }
  ```
</Expandable>

### `remove_moderator`

Removes the address as a moderator. Aborts with `EIsOwner` if attempting to remove the owner.

```rust theme={null}
public fun remove_moderator(moderation: &mut Moderation, user: address): (u8, u8)
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun remove_moderator(
        moderation: &mut Moderation,
        user: address
    ): (u8, u8) {
        let is_owner = is_owner(
            moderation,
            user
        );

        assert!(!is_owner, EIsOwner);

        moderation.moderation.remove(user);

        (MODERATOR_REMOVE, MODERATOR)
    }
  ```
</Expandable>
