Skip to main content

Forge

Trait Forge 

Source
pub trait Forge: Send + Sync {
Show 17 methods // Required methods fn kind(&self) -> ForgeKind; fn host(&self) -> &str; fn capabilities(&self, ns: &Namespace) -> Capabilities; fn begin_bind<'life0, 'async_trait>( &'life0 self, req: BindRequest, ) -> Pin<Box<dyn Future<Output = Result<BindStep>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn complete_bind<'life0, 'async_trait>( &'life0 self, cb: BindCallback, ) -> Pin<Box<dyn Future<Output = Result<NamespaceBinding>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn begin_account_link<'life0, 'life1, 'async_trait>( &'life0 self, member: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<LinkStep>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn complete_account_link<'life0, 'async_trait>( &'life0 self, cb: LinkCallback, ) -> Pin<Box<dyn Future<Output = Result<ForgeAccount>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn inspect<'life0, 'life1, 'async_trait>( &'life0 self, repo: &'life1 Resource, ) -> Pin<Box<dyn Future<Output = Result<RepoState>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn create_repo<'life0, 'life1, 'async_trait>( &'life0 self, spec: &'life1 RepoSpec, ) -> Pin<Box<dyn Future<Output = Result<RepoState>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn archive_repo<'life0, 'life1, 'async_trait>( &'life0 self, repo: &'life1 Resource, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn apply_roles<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, repo: &'life1 Resource, desired: &'life2 [RoleAssignment], unlisted: Unlisted, ) -> Pin<Box<dyn Future<Output = Result<ApplyReport>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn bootstrap_plan( &self, repo: &RepoSpec, cfg: &VgiConfig, ) -> Result<Vec<BootstrapStep>>; fn run_step<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, repo: &'life1 Resource, step: &'life2 BootstrapStep, ) -> Pin<Box<dyn Future<Output = Result<StepOutcome>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn parse_event( &self, headers: &HeaderMap, body: &[u8], ) -> Result<Option<ForgeEvent>>; // Provided methods fn normalize(&self, raw: &str) -> Result<Resource> { ... } fn map_role( &self, ns: &Namespace, rights: EffectiveRights, map: &RoleMap, ) -> ForgeRole { ... } fn diff(&self, observed: &RepoState, desired: &Projection) -> Vec<Drift> { ... }
}
Expand description

One forge implementation. Stateless apart from its credentials and the namespaces it has been told about; the core owns all desired state and hands the adapter a plan.

Object-safe (through async-trait) so a bridge can hold one Box<dyn Forge> per forge host and dispatch on a resource’s host. Methods with a sensible forge-neutral answer have a default; an adapter overrides only what its forge does differently.

Required Methods§

Source

fn kind(&self) -> ForgeKind

Which forge software this is.

Source

fn host(&self) -> &str

The forge host this adapter serves (github.com, a GHES host, codeberg.org). Every resource it accepts starts with it; a resource on another host is refused rather than sent to the wrong forge.

Source

fn capabilities(&self, ns: &Namespace) -> Capabilities

What this forge, and this namespace on it, can do. The core and the UX branch on this, never on Forge::kind.

Source

fn begin_bind<'life0, 'async_trait>( &'life0 self, req: BindRequest, ) -> Pin<Box<dyn Future<Output = Result<BindStep>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Start binding a namespace: where to send the admin.

Source

fn complete_bind<'life0, 'async_trait>( &'life0 self, cb: BindCallback, ) -> Pin<Box<dyn Future<Output = Result<NamespaceBinding>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Finish a bind from the forge’s callback. Validates the state nonce and that the credential landed on the expected owner.

Start linking a member’s forge account. member is their DID, for the adapter’s audit trail; nothing forge-side sees it.

Finish linking: the account’s numeric id and current login.

Source

fn inspect<'life0, 'life1, 'async_trait>( &'life0 self, repo: &'life1 Resource, ) -> Pin<Box<dyn Future<Output = Result<RepoState>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Observe a repository’s current state.

Source

fn create_repo<'life0, 'life1, 'async_trait>( &'life0 self, spec: &'life1 RepoSpec, ) -> Pin<Box<dyn Future<Output = Result<RepoState>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Create a repository. Refuses one that already exists with ForgeError::AlreadyExists — adopting it is a separate, elevated decision (§5.6), not something a retry should do silently.

Source

fn archive_repo<'life0, 'life1, 'async_trait>( &'life0 self, repo: &'life1 Resource, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Archive a repository. Idempotent.

Source

fn apply_roles<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, repo: &'life1 Resource, desired: &'life2 [RoleAssignment], unlisted: Unlisted, ) -> Pin<Box<dyn Future<Output = Result<ApplyReport>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Converge people’s direct roles on a repository to desired. Collaborators desired does not mention are handled per unlisted.

Source

fn bootstrap_plan( &self, repo: &RepoSpec, cfg: &VgiConfig, ) -> Result<Vec<BootstrapStep>>

The steps that turn commit trust on for this forge’s CI.

Source

fn run_step<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, repo: &'life1 Resource, step: &'life2 BootstrapStep, ) -> Pin<Box<dyn Future<Output = Result<StepOutcome>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Run one step, check-then-apply.

Source

fn parse_event( &self, headers: &HeaderMap, body: &[u8], ) -> Result<Option<ForgeEvent>>

Verify and translate a webhook. Ok(None) for a verified delivery the core has no use for; Err for one that failed verification — which must not be acted on.

Provided Methods§

Source

fn normalize(&self, raw: &str) -> Result<Resource>

Canonical form of a forge path. The default applies the owner[/repo] grammar GitHub and Forgejo share and refuses a resource on another host.

Source

fn map_role( &self, ns: &Namespace, rights: EffectiveRights, map: &RoleMap, ) -> ForgeRole

Rights → this forge’s role for one person on one repository in ns. The default asks map for a role and rounds it down onto the namespace’s ladder.

Source

fn diff(&self, observed: &RepoState, desired: &Projection) -> Vec<Drift>

Compare observed state with the projection.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§