pub trait TrackerAdapter {
// Required methods
fn tool(&self) -> Tool;
fn create_issue(
&mut self,
title: &str,
body: &str,
labels: &[String],
assignee: Option<&str>,
priority: Option<&str>,
status: &str,
) -> Result<String>;
fn update_issue(
&mut self,
remote_ref: &str,
title: &str,
body: &str,
labels: &[String],
assignee: Option<&str>,
priority: Option<&str>,
status: &str,
) -> Result<()>;
fn mark_done(&mut self, remote_ref: &str) -> Result<()>;
fn list_open(&mut self) -> Result<Vec<RemoteIssue>>;
fn done_via_status(&self) -> bool;
fn set_relations(
&mut self,
remote_ref: &str,
relations: &[MappedRelation],
) -> Result<()>;
fn set_projects(
&mut self,
remote_ref: &str,
projects: &[MappedProject],
) -> Result<()>;
fn set_epics(
&mut self,
remote_ref: &str,
epics: &[MappedEpic],
) -> Result<()>;
}Expand description
Common surface both tracker adapters implement so the orchestration is tool-agnostic.
status is the remote state/label already computed by the pure mapping
helpers (e.g. closed, Done, or the first work column). GitLab conveys
“done” via a separate close call (TrackerAdapter::mark_done); Linear
conveys it with -s Done (TrackerAdapter::done_via_status).
Required Methods§
fn tool(&self) -> Tool
Sourcefn create_issue(
&mut self,
title: &str,
body: &str,
labels: &[String],
assignee: Option<&str>,
priority: Option<&str>,
status: &str,
) -> Result<String>
fn create_issue( &mut self, title: &str, body: &str, labels: &[String], assignee: Option<&str>, priority: Option<&str>, status: &str, ) -> Result<String>
Create a remote issue and return its remote id (GitLab iid, Linear
identifier).
Sourcefn update_issue(
&mut self,
remote_ref: &str,
title: &str,
body: &str,
labels: &[String],
assignee: Option<&str>,
priority: Option<&str>,
status: &str,
) -> Result<()>
fn update_issue( &mut self, remote_ref: &str, title: &str, body: &str, labels: &[String], assignee: Option<&str>, priority: Option<&str>, status: &str, ) -> Result<()>
Update an existing remote issue in place.
Sourcefn mark_done(&mut self, remote_ref: &str) -> Result<()>
fn mark_done(&mut self, remote_ref: &str) -> Result<()>
Convey “done” (GitLab: issue close <id>). Only invoked when
done_via_status is false.
Sourcefn list_open(&mut self) -> Result<Vec<RemoteIssue>>
fn list_open(&mut self) -> Result<Vec<RemoteIssue>>
List open remote issues (the import source). Closed/done issues are excluded.
Sourcefn done_via_status(&self) -> bool
fn done_via_status(&self) -> bool
Linear sets done through the status flag; GitLab needs a separate close call.
Sourcefn set_relations(
&mut self,
remote_ref: &str,
relations: &[MappedRelation],
) -> Result<()>
fn set_relations( &mut self, remote_ref: &str, relations: &[MappedRelation], ) -> Result<()>
Send the relationships this tracker can express, after the issue itself exists (WP07 T030/T031).
Required, not defaulted. A default no-op would let a tracker be added that silently never syncs relationships — the failure mode is a local relation that appears to sync and does not, which is the same silent-loss shape as a dropped edge. Two implementors is a small price for making the omission a compile error.
The relationships arrive already filtered by
map_relation_to_remote, so an adapter never decides representability:
it sends what the shared seam says it can send, and reports the rest. A
blocks edge reaches here; a related edge never does.
Sourcefn set_projects(
&mut self,
remote_ref: &str,
projects: &[MappedProject],
) -> Result<()>
fn set_projects( &mut self, remote_ref: &str, projects: &[MappedProject], ) -> Result<()>
Send the project associations this tracker can express, after the issue itself exists (WP08 T036).
Required, not defaulted, for the same reason Self::set_relations is:
a default no-op would let a tracker be added that silently never syncs
project membership, which is the silent-loss shape C-005 forbids. Both
adapters implement PROJECT_WIRE_VERIFIED’s answer, which is “nothing”, and
the signature is why a future tracker cannot answer with a different shape.
The associations arrive already filtered by map_project_to_remote, so an
adapter never decides representability — and while PROJECT_WIRE_VERIFIED is
empty it never receives a sendable value either, so both implementations
return without spawning anything. A run that cannot express membership must
send nothing: an empty membership flag that the tool interpreted as
“clear it” would delete remote state on a run that had nothing to say, which
is the same trap set_relations avoids by returning early on an empty set.
Sourcefn set_epics(&mut self, remote_ref: &str, epics: &[MappedEpic]) -> Result<()>
fn set_epics(&mut self, remote_ref: &str, epics: &[MappedEpic]) -> Result<()>
Send the epic references this tracker can express, after the issue itself
exists (WP08, mission epics-work-items-01M3BYW4).
Required, not defaulted, for the reason Self::set_relations and
Self::set_projects give: a default no-op would let a tracker be added
that silently never syncs an epic reference, which is the silent-loss shape
C-007 forbids. The signature is why a future tracker cannot answer with a
different shape.
The references arrive already filtered by map_epic_to_remote, so an
adapter never decides representability. Both adapters implement
EPIC_WIRE_VERIFIED’s answer, which is “nothing”: neither glab nor
linear-cli carries an epic membership list, so both return without spawning
anything, and an empty set must spawn nothing (an empty flag the tool read as
“clear it” would delete remote state on a run with nothing to say — the same
trap set_relations avoids by returning early).
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".