> ## 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.

# Favorites

> Tracks user favorites, manages favorite counts, and status checks.

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

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

## Structs

### `Favorite`

Data on relationship created between a `User` and the content they want to favorite.

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

<Expandable title="Fields">
  ```rust theme={null}
    count: u64,
    created_at: u64,
    is_favorite: bool,
    updated_at: u64
  ```
</Expandable>

### `Favorites`

All of the relationships that exist between `User`s and the content they have favorited.

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

<Expandable title="Fields">
  ```rust theme={null}
    current_favorites: u64,
    favorites: sui::table::Table<address, Favorite>
  ```
</Expandable>

## Constants

Error code when attempting to favorite content that has already been favorited.

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

Error code when attempting to unfavorite content that has not been favorited.

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

## Functions

### `add`

Favorite the content.

```rust theme={null}
public fun add(favorites: &mut Favorites, key: address, timestamp: u64): u64
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun add(
        favorites: &mut Favorites,
        key: address,
        timestamp: u64
    ): u64 {
        let does_exist = favorites.favorites.contains(key);
        let mut favorite_count = 1;

        if (does_exist) {
            let favorite = favorites.favorites.borrow_mut(key);

            assert!(!favorite.is_favorite, EAlreadyFavorited);

            favorite.count = favorite.count + 1;
            favorite.is_favorite = true;
            favorite.updated_at = timestamp;

            favorite_count = favorite.count;
        } else {
            let favorite = Favorite {
                count: favorite_count,
                created_at: timestamp,
                is_favorite: true,
                updated_at: timestamp
            };

            favorites.favorites.add(key, favorite);
        };

        favorites.current_favorites = favorites.current_favorites + 1;

        favorite_count
    }
  ```
</Expandable>

### `assert_has_not_favorited`

Aborts with `EAlreadyFavorited` if the content has already been favorited.

```rust theme={null}
public fun assert_has_not_favorited(favorites: &Favorites, key: address)
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun assert_has_not_favorited(
        favorites: &Favorites,
        key: address
    ) {
        let is_favorite = is_favorite(
            favorites,
            key
        );

        assert!(!is_favorite, EAlreadyFavorited);
    }
  ```
</Expandable>

### `create`

Creates a new instance of `Favorites`.

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

<Expandable title="Implementation">
  ```rust theme={null}
    public fun create(
        ctx: &mut TxContext
    ): Favorites {
        let favorites = Favorites {
            current_favorites: 0,
            favorites: table::new(ctx)
        };

        favorites
    }
  ```
</Expandable>

### `get_count`

Gets the number of times the content has been favorited.

```rust theme={null}
public fun get_count(favorites: &Favorites, key: address): u64
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun get_count(
        favorites: &Favorites,
        key: address
    ): u64 {
        favorites.favorites[key].count
    }
  ```
</Expandable>

### `get_created_at`

Get timestamp of when the content was first favorited.

```rust theme={null}
public fun get_created_at(favorites: &Favorites, key: address): u64
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun get_created_at(
        favorites: &Favorites,
        key: address
    ): u64 {
        favorites.favorites[key].created_at
    }
  ```
</Expandable>

### `get_length`

Get the number of favorites on the content currently.

```rust theme={null}
public fun get_length(favorites: &Favorites): u64
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun get_length(
        favorites: &Favorites
    ): u64 {
        favorites.current_favorites
    }
  ```
</Expandable>

### `get_updated_at`

Get timestamp of when the content was most recently favorited.

```rust theme={null}
public fun get_updated_at(favorites: &Favorites, key: address): u64
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun get_updated_at(
        favorites: &Favorites,
        key: address
    ): u64 {
        favorites.favorites[key].updated_at
    }
  ```
</Expandable>

### `is_favorite`

Returns true or false based on whether the content has currently been favorited.

```rust theme={null}
public fun is_favorite(favorites: &Favorites, key: address): bool
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun is_favorite(
        favorites: &Favorites,
        key: address
    ): bool {
        favorites.favorites.contains(key) &&
        favorites.favorites[key].is_favorite
    }
  ```
</Expandable>

### `remove`

Unfavorite the content.

```rust theme={null}
public fun remove(favorites: &mut Favorites, key: address, timestamp: u64): u64
```

<Expandable title="Implementation">
  ```rust theme={null}
    public fun remove(
        favorites: &mut Favorites,
        key: address,
        timestamp: u64
    ): u64 {
        let favorite = favorites.favorites.borrow_mut(key);

        assert!(favorite.is_favorite, EIsNotFavorite);

        favorite.is_favorite = false;
        favorite.updated_at = timestamp;

        favorites.current_favorites = favorites.current_favorites - 1;

        favorite.count
    }
  ```
</Expandable>
