pub struct JiraClient { /* private fields */ }Implementations§
Source§impl JiraClient
impl JiraClient
Sourcepub fn new(
url: impl Into<String>,
project_key: impl Into<String>,
email: impl Into<String>,
token: SecretString,
) -> Self
pub fn new( url: impl Into<String>, project_key: impl Into<String>, email: impl Into<String>, token: SecretString, ) -> Self
Create a new Jira client. Flavor is auto-detected from the URL.
Sourcepub fn with_proxy(self, headers: HashMap<String, String>) -> Self
pub fn with_proxy(self, headers: HashMap<String, String>) -> Self
Configure proxy mode with extra headers added to every request.
When proxy is active, the provider’s own auth headers are suppressed —
the proxy handles authentication.
Note: instance_url is preserved for generating browse links.
Sourcepub fn with_instance_url(self, url: impl Into<String>) -> Self
pub fn with_instance_url(self, url: impl Into<String>) -> Self
Override the instance URL used for generating browse links. Useful when proxy URL differs from real Jira instance URL.
Sourcepub fn with_flavor(self, flavor: JiraFlavor) -> Self
pub fn with_flavor(self, flavor: JiraFlavor) -> Self
Override auto-detected flavor. Use when the URL doesn’t reflect the actual Jira deployment (e.g. proxy URL instead of real Jira URL).
Sourcepub fn with_base_url(
base_url: impl Into<String>,
project_key: impl Into<String>,
email: impl Into<String>,
token: SecretString,
flavor: bool,
) -> Self
pub fn with_base_url( base_url: impl Into<String>, project_key: impl Into<String>, email: impl Into<String>, token: SecretString, flavor: bool, ) -> Self
Create a new Jira client with explicit base URL (for testing with httpmock).
The base URL is used as-is (no /rest/api/N suffix appended).
Sourcepub async fn list_structures_for_metadata(
&self,
) -> Result<Vec<JiraStructureRef>>
pub async fn list_structures_for_metadata( &self, ) -> Result<Vec<JiraStructureRef>>
Fetch a compact list of accessible Structures for metadata enrichment.
Unlike Self::get_structures, this is intended to be called from a
metadata-assembly pipeline and swallows the “Structure plugin not
installed” error (HTTP 404, which the Structure endpoint returns as
a generic Jira “dead link” HTML page) into an empty Vec. The
resulting Ok(vec![]) is the “no structures are available here”
signal that downstream enrichers key on to decide whether to touch
the structureId parameter of Structure tools.
Credential / permission failures (401 Unauthorized, 403
Forbidden) still propagate — those indicate the caller’s
integration is misconfigured, not that the feature is absent, and
the metadata build should surface the error rather than silently
pretend no structures exist.
Sourcepub async fn fetch_fields(&self) -> Result<Vec<JiraField>>
pub async fn fetch_fields(&self) -> Result<Vec<JiraField>>
Fetch every field (system + custom) on the Jira instance.
Single round-trip — Jira returns all fields in one unpaginated
response. Caller is responsible for caching if it plans to call
repeatedly; for name → id lookups, prefer
resolve_field_id_by_name
which caches internally.
Sourcepub async fn resolve_field_id_by_name(
&self,
name: &str,
) -> Result<Option<String>>
pub async fn resolve_field_id_by_name( &self, name: &str, ) -> Result<Option<String>>
Resolve a Jira field name (e.g. "Epic Link", "Sprint",
"Epic Name") to its id (e.g. "customfield_10014").
Returns Ok(None) when no field with this exact name exists on
the instance — most often because the field is disabled,
renamed, or localised. Callers that depend on a specific field
should treat None as a hard error and surface a hint pointing
users at get_custom_fields for discovery.
The first lookup populates an in-memory cache (field_cache)
from GET /rest/api/{v}/field; subsequent lookups are
allocation-free and don’t hit the network. Concurrent first-time
lookups race-free thanks to tokio::sync::OnceCell.
Sourcepub async fn load_default_metadata(
&self,
strategy: MetadataLoadStrategy,
) -> Result<JiraMetadata>
pub async fn load_default_metadata( &self, strategy: MetadataLoadStrategy, ) -> Result<JiraMetadata>
Build a crate::metadata::JiraMetadata cache the schema
enricher can consume, with project selection driven by the
caller-supplied crate::metadata::MetadataLoadStrategy.
This is the supported entry point for downstream consumers
that don’t already have metadata loaded — they pick a
strategy, this method handles project discovery, per-project
metadata fetches, and MAX_ENRICHMENT_PROJECTS enforcement.
Strategies are intentionally explicit (no auto-default) so
callers think about which N projects make sense for their
surface area.
Strategy-driven entry point. Concrete strategies land
behind a match here; unwired variants still return
ProviderUnsupported so downstream callers can probe
safely.
Sourcepub async fn build_project_metadata(
&self,
project_key: &str,
) -> Result<JiraProjectMetadata>
pub async fn build_project_metadata( &self, project_key: &str, ) -> Result<JiraProjectMetadata>
Fetch and assemble crate::metadata::JiraProjectMetadata
for a single project — issue types, components, priorities,
link types, customfields. Building block reused by every
concrete MetadataLoadStrategy.
Issuance breakdown (5 round-trips per project, sequential):
GET /project/{key}forissueTypesGET /project/{key}/componentsGET /priority(instance-wide; same payload for every project but small)GET /issueLinkType(instance-wide)GET /field(instance-wide)
None of the instance-wide calls are memoised today — looping
over N projects issues 3·N redundant round-trips for
/priority//issueLinkType//field. Acceptable for the
MAX_ENRICHMENT_PROJECTS = 30 budget; a follow-up may wrap
the instance-wide responses in a tokio::sync::OnceCell
alongside field_cache if profiling justifies it.
Trait Implementations§
Source§impl IssueProvider for JiraClient
impl IssueProvider for JiraClient
Source§fn get_issues<'life0, 'async_trait>(
&'life0 self,
filter: IssueFilter,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<Issue>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_issues<'life0, 'async_trait>(
&'life0 self,
filter: IssueFilter,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<Issue>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn get_issue<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Issue>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_issue<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Issue>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn create_issue<'life0, 'async_trait>(
&'life0 self,
input: CreateIssueInput,
) -> Pin<Box<dyn Future<Output = Result<Issue>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn create_issue<'life0, 'async_trait>(
&'life0 self,
input: CreateIssueInput,
) -> Pin<Box<dyn Future<Output = Result<Issue>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn update_issue<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
input: UpdateIssueInput,
) -> Pin<Box<dyn Future<Output = Result<Issue>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn update_issue<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
input: UpdateIssueInput,
) -> Pin<Box<dyn Future<Output = Result<Issue>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_comments<'life0, 'life1, 'async_trait>(
&'life0 self,
issue_key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<Comment>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn add_comment<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
issue_key: &'life1 str,
body: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Comment>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Source§fn get_statuses<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<IssueStatus>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_statuses<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<IssueStatus>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn get_users<'life0, 'async_trait>(
&'life0 self,
options: GetUsersOptions,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<User>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_users<'life0, 'async_trait>(
&'life0 self,
options: GetUsersOptions,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<User>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn link_issues<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
source_key: &'life1 str,
target_key: &'life2 str,
link_type: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn link_issues<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
source_key: &'life1 str,
target_key: &'life2 str,
link_type: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Source§fn get_issue_relations<'life0, 'life1, 'async_trait>(
&'life0 self,
issue_key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<IssueRelations>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_issue_relations<'life0, 'life1, 'async_trait>(
&'life0 self,
issue_key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<IssueRelations>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn upload_attachment<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
issue_key: &'life1 str,
filename: &'life2 str,
data: &'life3 [u8],
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn upload_attachment<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
issue_key: &'life1 str,
filename: &'life2 str,
data: &'life3 [u8],
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Source§fn get_issue_attachments<'life0, 'life1, 'async_trait>(
&'life0 self,
issue_key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<AssetMeta>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_issue_attachments<'life0, 'life1, 'async_trait>(
&'life0 self,
issue_key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<AssetMeta>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn download_attachment<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_issue_key: &'life1 str,
asset_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn download_attachment<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_issue_key: &'life1 str,
asset_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Source§fn delete_attachment<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_issue_key: &'life1 str,
asset_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn delete_attachment<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_issue_key: &'life1 str,
asset_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Source§fn asset_capabilities(&self) -> AssetCapabilities
fn asset_capabilities(&self) -> AssetCapabilities
ProviderUnsupported.Source§fn get_structures<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<Structure>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_structures<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<Structure>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn get_structure_forest<'life0, 'async_trait>(
&'life0 self,
structure_id: u64,
options: GetForestOptions,
) -> Pin<Box<dyn Future<Output = Result<StructureForest>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_structure_forest<'life0, 'async_trait>(
&'life0 self,
structure_id: u64,
options: GetForestOptions,
) -> Pin<Box<dyn Future<Output = Result<StructureForest>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn add_structure_rows<'life0, 'async_trait>(
&'life0 self,
structure_id: u64,
input: AddStructureRowsInput,
) -> Pin<Box<dyn Future<Output = Result<ForestModifyResult>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn add_structure_rows<'life0, 'async_trait>(
&'life0 self,
structure_id: u64,
input: AddStructureRowsInput,
) -> Pin<Box<dyn Future<Output = Result<ForestModifyResult>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn move_structure_rows<'life0, 'async_trait>(
&'life0 self,
structure_id: u64,
input: MoveStructureRowsInput,
) -> Pin<Box<dyn Future<Output = Result<ForestModifyResult>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn move_structure_rows<'life0, 'async_trait>(
&'life0 self,
structure_id: u64,
input: MoveStructureRowsInput,
) -> Pin<Box<dyn Future<Output = Result<ForestModifyResult>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn remove_structure_row<'life0, 'async_trait>(
&'life0 self,
structure_id: u64,
row_id: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn remove_structure_row<'life0, 'async_trait>(
&'life0 self,
structure_id: u64,
row_id: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn get_structure_values<'life0, 'async_trait>(
&'life0 self,
input: GetStructureValuesInput,
) -> Pin<Box<dyn Future<Output = Result<StructureValues>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_structure_values<'life0, 'async_trait>(
&'life0 self,
input: GetStructureValuesInput,
) -> Pin<Box<dyn Future<Output = Result<StructureValues>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn get_structure_views<'life0, 'async_trait>(
&'life0 self,
structure_id: u64,
view_id: Option<u64>,
) -> Pin<Box<dyn Future<Output = Result<Vec<StructureView>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_structure_views<'life0, 'async_trait>(
&'life0 self,
structure_id: u64,
view_id: Option<u64>,
) -> Pin<Box<dyn Future<Output = Result<Vec<StructureView>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn save_structure_view<'life0, 'async_trait>(
&'life0 self,
input: SaveStructureViewInput,
) -> Pin<Box<dyn Future<Output = Result<StructureView>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn save_structure_view<'life0, 'async_trait>(
&'life0 self,
input: SaveStructureViewInput,
) -> Pin<Box<dyn Future<Output = Result<StructureView>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn create_structure<'life0, 'async_trait>(
&'life0 self,
input: CreateStructureInput,
) -> Pin<Box<dyn Future<Output = Result<Structure>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn create_structure<'life0, 'async_trait>(
&'life0 self,
input: CreateStructureInput,
) -> Pin<Box<dyn Future<Output = Result<Structure>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn get_structure_generators<'life0, 'async_trait>(
&'life0 self,
structure_id: u64,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<StructureGenerator>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_structure_generators<'life0, 'async_trait>(
&'life0 self,
structure_id: u64,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<StructureGenerator>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn add_structure_generator<'life0, 'async_trait>(
&'life0 self,
input: AddStructureGeneratorInput,
) -> Pin<Box<dyn Future<Output = Result<StructureGenerator>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn add_structure_generator<'life0, 'async_trait>(
&'life0 self,
input: AddStructureGeneratorInput,
) -> Pin<Box<dyn Future<Output = Result<StructureGenerator>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn sync_structure_generator<'life0, 'async_trait>(
&'life0 self,
input: SyncStructureGeneratorInput,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn sync_structure_generator<'life0, 'async_trait>(
&'life0 self,
input: SyncStructureGeneratorInput,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn delete_structure<'life0, 'async_trait>(
&'life0 self,
structure_id: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn delete_structure<'life0, 'async_trait>(
&'life0 self,
structure_id: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn update_structure_automation<'life0, 'async_trait>(
&'life0 self,
input: UpdateStructureAutomationInput,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn update_structure_automation<'life0, 'async_trait>(
&'life0 self,
input: UpdateStructureAutomationInput,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn trigger_structure_automation<'life0, 'async_trait>(
&'life0 self,
structure_id: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn trigger_structure_automation<'life0, 'async_trait>(
&'life0 self,
structure_id: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn get_board_sprints<'life0, 'async_trait>(
&'life0 self,
board_id: u64,
state: SprintState,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<Sprint>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_board_sprints<'life0, 'async_trait>(
&'life0 self,
board_id: u64,
state: SprintState,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<Sprint>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn assign_to_sprint<'life0, 'async_trait>(
&'life0 self,
input: AssignToSprintInput,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn assign_to_sprint<'life0, 'async_trait>(
&'life0 self,
input: AssignToSprintInput,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn list_project_versions<'life0, 'async_trait>(
&'life0 self,
params: ListProjectVersionsParams,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<ProjectVersion>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_project_versions<'life0, 'async_trait>(
&'life0 self,
params: ListProjectVersionsParams,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<ProjectVersion>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fixVersion targets) for a project.
Default: ProviderUnsupported.Source§fn upsert_project_version<'life0, 'async_trait>(
&'life0 self,
input: UpsertProjectVersionInput,
) -> Pin<Box<dyn Future<Output = Result<ProjectVersion>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn upsert_project_version<'life0, 'async_trait>(
&'life0 self,
input: UpsertProjectVersionInput,
) -> Pin<Box<dyn Future<Output = Result<ProjectVersion>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
(project, name).
Partial update: optional fields left as None are not touched.
Default: ProviderUnsupported.Source§fn list_custom_fields<'life0, 'async_trait>(
&'life0 self,
params: ListCustomFieldsParams,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<CustomFieldDescriptor>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_custom_fields<'life0, 'async_trait>(
&'life0 self,
params: ListCustomFieldsParams,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<CustomFieldDescriptor>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
customfield_* ids of an instance
without hardcoding them. Default impl returns
ProviderUnsupported — providers without a real customfield
concept (GitHub, GitLab) keep that default.Source§fn provider_name(&self) -> &'static str
fn provider_name(&self) -> &'static str
Source§fn unlink_issues<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
_source_key: &'life1 str,
_target_key: &'life2 str,
_link_type: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Self: 'async_trait,
fn unlink_issues<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
_source_key: &'life1 str,
_target_key: &'life2 str,
_link_type: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Self: 'async_trait,
Source§fn set_custom_fields<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_issue_key: &'life1 str,
_fields: &'life2 [Value],
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn set_custom_fields<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_issue_key: &'life1 str,
_fields: &'life2 [Value],
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
{"id": "field_id", "value": <value>}.
Default is no-op — override in providers that support custom fields (e.g., ClickUp).Source§impl MergeRequestProvider for JiraClient
impl MergeRequestProvider for JiraClient
Source§fn provider_name(&self) -> &'static str
fn provider_name(&self) -> &'static str
Source§fn get_merge_requests<'life0, 'async_trait>(
&'life0 self,
_filter: MrFilter,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<MergeRequest>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn get_merge_requests<'life0, 'async_trait>(
&'life0 self,
_filter: MrFilter,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<MergeRequest>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Source§fn get_merge_request<'life0, 'life1, 'async_trait>(
&'life0 self,
_key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<MergeRequest, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn get_merge_request<'life0, 'life1, 'async_trait>(
&'life0 self,
_key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<MergeRequest, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Source§fn get_discussions<'life0, 'life1, 'async_trait>(
&'life0 self,
_mr_key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<Discussion>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn get_discussions<'life0, 'life1, 'async_trait>(
&'life0 self,
_mr_key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<Discussion>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn get_diffs<'life0, 'life1, 'async_trait>(
&'life0 self,
_mr_key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<FileDiff>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn add_comment<'life0, 'life1, 'async_trait>(
&'life0 self,
_mr_key: &'life1 str,
_input: CreateCommentInput,
) -> Pin<Box<dyn Future<Output = Result<Comment, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Source§fn create_merge_request<'life0, 'async_trait>(
&'life0 self,
_input: CreateMergeRequestInput,
) -> Pin<Box<dyn Future<Output = Result<MergeRequest, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn create_merge_request<'life0, 'async_trait>(
&'life0 self,
_input: CreateMergeRequestInput,
) -> Pin<Box<dyn Future<Output = Result<MergeRequest, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Source§fn update_merge_request<'life0, 'life1, 'async_trait>(
&'life0 self,
_key: &'life1 str,
_input: UpdateMergeRequestInput,
) -> Pin<Box<dyn Future<Output = Result<MergeRequest, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn update_merge_request<'life0, 'life1, 'async_trait>(
&'life0 self,
_key: &'life1 str,
_input: UpdateMergeRequestInput,
) -> Pin<Box<dyn Future<Output = Result<MergeRequest, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Source§fn get_releases<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<Release>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn get_releases<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<ProviderResult<Release>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Source§fn get_mr_attachments<'life0, 'life1, 'async_trait>(
&'life0 self,
_mr_key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<AssetMeta>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn get_mr_attachments<'life0, 'life1, 'async_trait>(
&'life0 self,
_mr_key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<AssetMeta>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn download_mr_attachment<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_mr_key: &'life1 str,
_asset_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn delete_mr_attachment<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_mr_key: &'life1 str,
_asset_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Source§impl PipelineProvider for JiraClient
impl PipelineProvider for JiraClient
Source§fn provider_name(&self) -> &'static str
fn provider_name(&self) -> &'static str
fn get_pipeline<'life0, 'async_trait>(
&'life0 self,
_input: GetPipelineInput,
) -> Pin<Box<dyn Future<Output = Result<PipelineInfo, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Source§fn get_job_logs<'life0, 'life1, 'async_trait>(
&'life0 self,
_job_id: &'life1 str,
_options: JobLogOptions,
) -> Pin<Box<dyn Future<Output = Result<JobLogOutput, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn get_job_logs<'life0, 'life1, 'async_trait>(
&'life0 self,
_job_id: &'life1 str,
_options: JobLogOptions,
) -> Pin<Box<dyn Future<Output = Result<JobLogOutput, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Source§impl Provider for JiraClient
impl Provider for JiraClient
Source§impl UserProvider for JiraClient
impl UserProvider for JiraClient
Source§fn provider_name(&self) -> &'static str
fn provider_name(&self) -> &'static str
Source§fn get_user_profile<'life0, 'life1, 'async_trait>(
&'life0 self,
user_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<User>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_user_profile<'life0, 'life1, 'async_trait>(
&'life0 self,
user_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<User>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
U0123, Jira
accountId / name, ClickUp user id, etc.).Source§fn lookup_user_by_email<'life0, 'life1, 'async_trait>(
&'life0 self,
email: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<User>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn lookup_user_by_email<'life0, 'life1, 'async_trait>(
&'life0 self,
email: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<User>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
None if the provider can issue
the query but there is no match, Error::ProviderUnsupported
when the provider simply doesn’t expose an email lookup.