# Sharing Code Between Commands

The commands of one aggregate usually act on the same kind of subject, guarded by the same preconditions, and their deciders check the same things first. Write these once instead of for every command.

## Sharing Subjects and Preconditions

Define the subject and the preconditions on a generic struct of their own, which holds the subject together with whatever is particular to a command, and implement `Command` once for it. Every command of the aggregate then consists of only its particular fields, and the generic struct around it makes it a `Command`:

```rust
#[derive(Clone)]
struct OnBook<T> {
  book: Subject,
  action: T,
}

impl<T> Command for OnBook<T> {
  fn subject(&self) -> Subject {
    self.book.clone()
  }

  fn preconditions(&self) -> Vec<Precondition> {
    vec![Precondition::on_state_read()]
  }
}

#[derive(Clone)]
struct AcquireBook {
  title: String,
  author: String,
  isbn: String,
}

#[derive(Clone)]
struct BorrowBook {
  reader_id: String,
  borrowed_until: String,
}

#[derive(Clone)]
struct ReturnBook;
```

A command then names its book through the generic struct, as in `OnBook { book: BOOKS.build(&["42"]), action: BorrowBook { reader_id: "23".to_owned(), borrowed_until: "2026-10-24".to_owned() } }`, and a decider for `OnBook<BorrowBook>` reads the book as `command.book`, and the rest as `command.action.reader_id`.

The command that creates a book can use the generic struct, too, since `on_state_read` requires a subject without any events to still be pristine (see **[Guarding Against Concurrent Changes](/docs/architecturekit/rust/using-preconditions#guarding-against-concurrent-changes)**). That is different if the generic struct checks the revision of the caller instead (see **[Checking the Revision of the Caller](/docs/architecturekit/rust/using-preconditions#checking-the-revision-of-the-caller)**): a new book has no revision yet. Then the creating command is a command of its own, and prevents duplicates itself:

```rust
use architecturekit::Revision;

#[derive(Clone)]
struct OnBook<T> {
  book: Subject,
  expected_event_id: Revision,
  action: T,
}

impl<T> Command for OnBook<T> {
  fn subject(&self) -> Subject {
    self.book.clone()
  }

  fn preconditions(&self) -> Vec<Precondition> {
    vec![Precondition::on_event_id(self.subject(), self.expected_event_id)]
  }
}

#[derive(Clone)]
struct AcquireBook {
  book: Subject,
  title: String,
  author: String,
  isbn: String,
}

impl Command for AcquireBook {
  fn subject(&self) -> Subject {
    self.book.clone()
  }

  fn preconditions(&self) -> Vec<Precondition> {
    vec![Precondition::on_pristine_subject(self.subject())]
  }
}
```

## Sharing Checks

Most deciders of an aggregate first check that it exists. Write that check once, as a function that returns a domain error, and call it with `?` at the beginning of every decider that needs it:

```rust
use architecturekit::{Decider, DomainError};

fn require_acquired(book: &Book, subject: &Subject) -> Result<(), DomainError> {
  if !book.is_acquired {
    return Err(DomainError::new(format!("{subject} does not exist")));
  }

  Ok(())
}

fn borrow_book() -> Decider<OnBook<BorrowBook>, Book, DomainError> {
  Decider::new(|command: OnBook<BorrowBook>, book: Book| async move {
    require_acquired(&book, &command.book)?;
    if book.is_borrowed {
      return Err(DomainError::new(format!("{} is already borrowed", command.book)));
    }

    Ok(vec![BookEvent::Borrowed(BookBorrowed {
      borrowed_by: command.action.reader_id,
      borrowed_until: command.action.borrowed_until,
    })])
  })
}
```

*Note that only the state knows what it means for an aggregate to exist, which is why the kit does not check it. The precondition that requires an existing subject protects the write (see **[Requiring an Existing Subject](/docs/architecturekit/rust/using-preconditions#requiring-an-existing-subject)**), but it fails with a conflict, which is transient. A check in the decider answers a command on a book that does not exist with a domain error instead.*
