# Understanding the Seam Architecture in pgrust: Breaking Dependency Cycles with Compile-Time Indirection

> Discover the seam architecture in pgrust. Learn how the seam! macro uses compile-time indirection to break dependency cycles and separate interfaces from implementations.

- Repository: [Michael Malis/pgrust](https://github.com/malisper/pgrust)
- Tags: internals
- Published: 2026-07-13

---

**The seam architecture in pgrust uses compile-time indirection through the `seam!` macro to replace direct function calls with runtime-filled slots, breaking circular dependencies by separating interface declarations from implementations.**

The **pgrust** project (malisper/pgrust) reimplements PostgreSQL in Rust while maintaining a strictly acyclic crate dependency graph. To solve the tight coupling inherent in database systems—where modules often need to call each other—the codebase employs a novel seam architecture that shifts linkage from compile-time to runtime without sacrificing type safety or performance.

## What Is the Seam Architecture in pgrust?

### The Core Concept: Compile-Time Indirection

A **seam** is a compile-time indirection point that replaces a direct function call with a slot that can be filled at runtime. In pgrust, the `seam!` macro—defined in [[`crates/_support/seam/seam_core/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/_support/seam/seam_core/src/lib.rs)](https://github.com/malisper/pgrust/blob/main/crates/_support/seam/seam_core/src/lib.rs)—expands to a module containing three public items:

- **`set(f)`** – Installs the concrete implementation. Can only be called once.
- **`call(..)`** – Invokes the installed implementation; panics if the seam is not yet initialized.
- **`is_installed()`** – Returns whether a concrete implementation has been registered.

This mechanism allows crates to agree on function signatures at compile time while deferring the actual dependency linking until program startup.

## How the Seam Architecture Breaks Dependency Cycles

The architecture eliminates circular dependencies through a four-step ownership pattern that separates contracts from implementations.

### Step 1: Separate Seams Crates

For any crate **X** that needs to expose functions externally, a companion crate **X-seams** is created. This crate contains only `seam!` declarations and never depends on the concrete implementation of **X**. For example, [`port_pqsignal_seams`](https://github.com/malisper/pgrust/blob/main/crates/port/port_pqsignal_seams/src/lib.rs) declares signal-handling slots without importing the actual signal implementation.

### Step 2: Implementation Crates Depend on Their Own Seams

The original crate **X** adds a dependency on **X-seams** and installs its implementation inside an `init_seams()` function. In [[`crates/port/port_pqsignal/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/port/port_pqsignal/src/lib.rs)](https://github.com/malisper/pgrust/blob/main/crates/port/port_pqsignal/src/lib.rs), the initialization looks like this:

```rust
pub fn init_seams() {
    port_pqsignal_seams::pqsignal::set(pqsignal_be);
}

```

This allows the implementation to reside in the original crate while remaining invisible to consumers at compile time.

### Step 3: Consumers Call Through the Seam

Consumer crates depend only on the lightweight **X-seams** crate, not on **X** itself. They invoke functionality through the seam slot:

```rust
use port_pqsignal_seams::pqsignal;

fn handle_signal() {
    // Calls the implementation installed by port_pqsignal
    pqsignal::call(signal_number);
}

```

Because the consumer only sees the seam declaration in [[`port_pqsignal_seams/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/port_pqsignal_seams/src/lib.rs)](https://github.com/malisper/pgrust/blob/main/crates/port/port_pqsignal_seams/src/lib.rs), the build graph remains acyclic.

### Step 4: Runtime Initialization with seams-init

The special **`seams-init`** crate orchestrates startup. It iterates over all crates in the workspace and invokes each `init_seams()` exactly once before any consumer code runs. The init runtime is defined in [[`crates/_support/seam/init/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/_support/seam/init/src/lib.rs)](https://github.com/malisper/pgrust/blob/main/crates/_support/seam/init/src/lib.rs).

This produces a unidirectional dependency graph:

```

consumer ─► X-seams ─► (runtime) X (installs)
        ↘︎                 ↗︎
         ──────► seams-init (calls X::init_seams())

```

## Practical Example: Implementing a Seam in pgrust

### Declaring the Seam

First, create a `-seams` crate that declares the interface:

```rust
// crates/myfeature_seams/src/lib.rs
seam_core::seam!(
    /// Executes the core logic of MyFeature.
    pub fn do_work(arg: i32) -> i32
);

```

### Installing the Implementation

The owning crate implements the logic and registers it during initialization:

```rust
// crates/myfeature/src/lib.rs
pub fn init_seams() {
    myfeature_seams::do_work::set(|arg| arg * 2); // concrete implementation
}

```

### Calling from Consumer Code

Downstream crates depend only on `myfeature_seams`, not `myfeature`:

```rust
// crates/consumer/src/lib.rs
use myfeature_seams::do_work;

pub fn run() -> i32 {
    // Panics if myfeature::init_seams() has not been called yet.
    do_work::call(21)
}

```

### Orchestrating Startup

Finally, ensure all seams are installed before use:

```rust
// crates/seams_init/src/lib.rs
pub fn init_all() {
    myfeature::init_seams();   // repeat for each crate that owns seams
    // … other init_seams() calls …
}

```

Running `seams_init::init_all()` at program entry guarantees that `do_work::call` executes safely.

## Key Source Files in the pgrust Seam Architecture

- **[[`crates/_support/seam/seam_core/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/_support/seam/seam_core/src/lib.rs)](https://github.com/malisper/pgrust/blob/main/crates/_support/seam/seam_core/src/lib.rs)** – Defines the `seam!` macro and the slot mechanics (`set`, `call`, `is_installed`).
- **[[`crates/_support/seam/init/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/_support/seam/init/src/lib.rs)](https://github.com/malisper/pgrust/blob/main/crates/_support/seam/init/src/lib.rs)** – Runtime entry point that invokes every crate's `init_seams()`.
- **[[`crates/port/port_pqsignal_seams/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/port/port_pqsignal_seams/src/lib.rs)](https://github.com/malisper/pgrust/blob/main/crates/port/port_pqsignal_seams/src/lib.rs)** – Real-world example of a seams crate for signal handling.
- **[[`crates/port/port_pqsignal/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/port/port_pqsignal/src/lib.rs)](https://github.com/malisper/pgrust/blob/main/crates/port/port_pqsignal/src/lib.rs)** – Implementation crate that installs signal handlers into the seam.
- **[[`crates/backend/utils/time/snapmgr_seams/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/time/snapmgr_seams/src/lib.rs)](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/time/snapmgr_seams/src/lib.rs)** – Time-snapshot manager interface declarations.
- **[[`crates/backend/utils/time/snapmgr/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/time/snapmgr/src/lib.rs)](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/time/snapmgr/src/lib.rs)** – Concrete implementation wiring into snapmgr seams.

## Summary

- The **seam architecture** in pgrust replaces direct function calls with runtime-filled slots declared via the `seam!` macro.
- **Dependency cycles break** by separating interface declarations (`X-seams` crate) from implementations (`X` crate).
- **Consumers** depend only on lightweight seams crates, never on the concrete implementations.
- **Initialization** happens once at startup via the `seams-init` crate, which calls each module's `init_seams()` function before any consumer code executes.
- The pattern keeps the Rust build graph strictly acyclic while preserving zero-cost runtime performance.

## Frequently Asked Questions

### What happens if a seam is called before initialization?

The `call()` function will **panic** at runtime if invoked before the corresponding `set()` has been called. This is by design—the `seams-init` crate guarantees that all `init_seams()` functions run before any consumer code, making this panic a safety net for initialization ordering bugs rather than an expected runtime path.

### Why not use trait objects or dependency injection instead of seams?

Trait objects require `dyn` dispatch and boxing, which introduces vtable overhead and allocation complexity. The seam architecture uses **static dispatch** through function pointers filled at startup, maintaining zero-cost abstraction characteristics while still breaking compile-time cycles. It also integrates cleanly with pgrust's existing C-to-Rust FFI boundaries where trait objects would be cumbersome.

### How does the seam! macro work technically?

The `seam!` macro, defined in [[`seam_core/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/seam_core/src/lib.rs)](https://github.com/malisper/pgrust/blob/main/crates/_support/seam/seam_core/src/lib.rs), expands to a module containing a thread-safe static `OnceCell` or equivalent storage. The `set` method writes a function pointer into this storage exactly once, while `call` reads and invokes that pointer. This generates minimal overhead—just a pointer indirection compared to a direct function call.

### Can seams be used for async functions?

While the analysis focuses on synchronous signatures, the architecture supports any function type that can be stored as a function pointer or closure. Async seams would require boxing the future or using `async fn` pointers, which the underlying storage in `seam_core` accommodates provided the function signature matches the declaration in the `-seams` crate.