Skip to main content

Jira

Struct Jira 

Source
pub struct Jira { /* private fields */ }
Expand description

Jira API client with session management capabilities.

This client handles authentication, session caching, and issue retrieval from Jira instances. It implements the Session trait for automatic credential management and retry logic.

§Thread Safety

The client is not thread-safe due to mutable retry state. Each thread should use its own client instance for concurrent operations.

§Session Lifecycle

  1. Initialization: Client created with configuration
  2. Authentication: Credentials prompted when first needed
  3. Session Caching: Successful sessions stored for reuse
  4. Automatic Retry: Expired sessions trigger re-authentication
  5. Error Handling: Persistent failures return empty results

Implementations§

Source§

impl Jira

Source

pub fn new(config: &JiraConfig) -> Self

Creates a new Jira API client instance.

Initializes the HTTP client with default settings suitable for Jira API interactions. The client is configured for JSON requests and includes appropriate timeout and connection settings.

§Arguments
  • config - Configuration containing Jira URL and login information
§Examples
use kasl::api::jira::{Jira, JiraConfig};

let config = JiraConfig {
    login: "username".to_string(),
    api_url: "https://jira.company.com".to_string(),
    completed_statuses: Vec::new(),
};
let jira = Jira::new(&config);
Source

pub async fn get_completed_issues( &mut self, date: &NaiveDate, ) -> Result<Vec<JiraIssue>>

Retrieves all issues completed by the current user on a specific date.

This method performs a sophisticated issue search using JQL (Jira Query Language) to find issues that were marked as completed on the specified date. The search includes robust error handling and automatic session management with retry logic.

§JQL Query Details

The search uses the following criteria:

  • Resolution Date: Issues resolved within the full day range (00:00 to 23:59)
  • Assignee Filter: Only issues assigned to the current user (currentUser())
§Session Management

The method implements sophisticated session handling:

  1. Session Retrieval: Get or create a valid session token using the Session trait
  2. API Request: Execute the JQL search with session cookie authentication
  3. Error Handling: Detect HTTP 401 (Unauthorized) responses indicating expired sessions
  4. Automatic Retry: Clear cached session and retry authentication up to the limit
  5. Graceful Degradation: Return empty results on persistent authentication failures
§Error Recovery Strategy

Unlike other API integrations, Jira errors are allowed to propagate rather than returning empty results silently. This is because Jira data is typically more critical for work tracking, and users should be aware of connection issues.

However, authentication failures are handled gracefully with automatic retry logic and eventual fallback to empty results after exhausting retries.

§Date Handling

The method formats the provided date to ensure proper JQL syntax and covers the entire day from midnight to 23:59 to capture all possible resolution times within the target date.

§Arguments
  • date - The date to search for completed issues (in any timezone)
§Returns

Returns a vector of JiraIssue objects representing completed work. Returns an empty vector if:

  • No issues are found matching the criteria
  • Authentication fails persistently after all retries
  • Network errors occur during the request
§Errors

May return errors for:

  • JSON parsing failures in API responses
  • Unexpected HTTP response formats
  • Session token formatting errors

Network errors and authentication failures are handled gracefully and result in empty results rather than propagated errors.

§Examples
let config = JiraConfig {
    login: "username".to_string(),
    api_url: "https://jira.company.com".to_string(),
    completed_statuses: Vec::new(),
};
let mut jira = Jira::new(&config);

let today = chrono::Local::now().date_naive();
let issues = jira.get_completed_issues(&today).await?;

for issue in issues {
    println!("Completed: {} - {}", issue.key, issue.fields.summary);
}
Source

pub async fn get_assigned_open_issues( &mut self, extra_field_ids: &[String], ) -> Result<Vec<JiraIssue>>

Fetches open issues currently assigned to the authenticated user.

Uses JQL assignee = currentUser() AND resolution is EMPTY. Paginates through all matching issues (startAt / total). Extra field ids (custom fields such as Scoring) are included in the fields query.

Auth failures and network errors return an empty list (same pattern as [get_completed_issues]) so callers can keep polling safely.

Source

pub async fn get_assigned_open_issues_noninteractive( &mut self, extra_field_ids: &[String], ) -> Result<Option<Vec<JiraIssue>>>

Like [get_assigned_open_issues], but never prompts for a password.

Uses a cached session cookie and/or encrypted .jira_secret. Returns Ok(None) when neither is available so background daemons can skip the poll without blocking on stdin.

Source

pub fn issue_browse_url(&self, key: &str) -> String

Builds a browse URL for an issue key using this client’s API base.

Source

pub fn priority_rank(priority: &Option<JiraPriority>) -> i32

Maps a Jira priority id to a sortable rank (lower = more urgent).

Source

pub fn extract_number(value: &Value) -> Option<f64>

Extracts a numeric value from a Jira custom-field JSON value.

Supports bare numbers, numeric strings, and objects with value / amount.

Source

pub fn sort_value_from_issue(issue: &JiraIssue, field_id: &str) -> Option<f64>

Reads a numeric custom field from issue extras by field id.

Trait Implementations§

Source§

impl Debug for Jira

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Session for Jira

Source§

async fn login(&self) -> Result<String>

Performs session-based authentication with Jira.

This method implements Jira’s session authentication flow using the REST API. It sends user credentials to the authentication endpoint and receives a session cookie that can be used for subsequent requests.

§Authentication Process
  1. Credential Validation: Ensures credentials are set before proceeding
  2. HTTP Request: POST to the session authentication endpoint with JSON credentials
  3. Response Validation: Checks for successful HTTP status codes
  4. Cookie Extraction: Parses session information from the response
  5. Format Preparation: Creates properly formatted cookie string for headers

The returned session ID is formatted as {cookie_name}={cookie_value} and should be included in the Cookie header of subsequent API requests.

§Returns

Returns a formatted session cookie string on successful authentication.

§Errors

Returns an error if:

  • No credentials have been set (programming error)
  • HTTP request fails due to network issues
  • Credentials are invalid (401 response)
  • Jira returns an unexpected response format
  • Session parsing fails
Source§

fn set_credentials(&mut self, password: &str) -> Result<()>

Sets user credentials for Jira authentication.

Stores the provided username and password in memory for use during the authentication process. This method is called by the session management system when credentials are needed.

§Security Notes
  • Credentials are only stored in memory temporarily
  • Password is stored in plain text for authentication
  • No persistence to disk or configuration files
  • Credentials are cleared after successful authentication
§Arguments
  • password - The user’s Jira password in plain text
§Returns

Always returns Ok(()) as this operation cannot fail.

Source§

fn session_id_file(&self) -> &str

Returns the filename for storing Jira session tokens.

The session file is stored in the user’s application data directory and contains the cached session token for automatic login restoration.

Source§

fn secret(&self) -> Secret

Returns a configured Secret instance for secure password prompting.

The Secret manager handles secure password input with hidden characters and optional encrypted caching in the user’s data directory.

§Returns

A configured Secret instance with Jira-specific prompts and file names.

Source§

fn retry(&self) -> i32

Returns the current authentication retry count.

Used by the session management system to track failed authentication attempts and implement retry limits.

Source§

fn inc_retry(&mut self)

Increments the authentication retry counter.

Called after each failed authentication attempt to track progress toward the maximum retry limit defined in the session management system.

Source§

fn reset_retry(&mut self)

Resets the authentication retry counter to zero.

Called after successful authentication to ensure future session requests start with a clean slate.

Source§

async fn get_session_id(&mut self) -> Result<String>

Retrieves or establishes a valid session ID. Read more
Source§

fn read_session_id(file_name: &str) -> Result<String>

Reads a session ID from the specified file. Read more
Source§

fn write_session_id(file_name: &str, session_id: &str) -> Result<()>

Writes a session ID to the specified file. Read more
Source§

fn delete_session_id(&self) -> Result<()>

Deletes the cached session file. Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for Jira

§

impl !UnwindSafe for Jira

§

impl Freeze for Jira

§

impl Send for Jira

§

impl Sync for Jira

§

impl Unpin for Jira

§

impl UnsafeUnpin for Jira

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more