pub struct Client { /* private fields */ }Expand description
A configured Tracker client.
Implementations§
Source§impl Client
impl Client
pub fn new(config: &ClientConfig) -> Result<Self, ApiError>
Sourcepub async fn myself(&self) -> Result<User, ApiError>
pub async fn myself(&self) -> Result<User, ApiError>
GET /v3/myself — the cheapest call that proves the whole chain works:
token, organisation header, and network.
Sourcepub async fn issue(&self, key: &str) -> Result<(Issue, Value), ApiError>
pub async fn issue(&self, key: &str) -> Result<(Issue, Value), ApiError>
One issue, both normalised and raw.
The raw payload travels alongside so that --json-raw does not cost a
second request, and so that a field we do not model is still reachable.
Sourcepub async fn issue_links(&self, key: &str) -> Result<Vec<Link>, ApiError>
pub async fn issue_links(&self, key: &str) -> Result<Vec<Link>, ApiError>
The links of an issue, with their direction resolved.
Tracker keeps links on their own endpoint, so the compact issue view costs two requests. Showing links is worth that: “what blocks this” is the question that follows “what is this”, and making the caller ask twice costs more than one round trip (ADR 3).
Sourcepub async fn issue_remote_links(
&self,
key: &str,
) -> Result<Vec<RemoteLink>, ApiError>
pub async fn issue_remote_links( &self, key: &str, ) -> Result<Vec<RemoteLink>, ApiError>
GET /v3/issues/{key}/remotelinks — the links that leave Tracker.
Its own request rather than a second section of Self::issue_links:
most issues have none, and making every issue links pay for a request
that usually answers [] is the wrong trade.
Sourcepub async fn search(
&self,
query: &str,
page: u32,
per_page: u32,
) -> Result<Page<Issue>, ApiError>
pub async fn search( &self, query: &str, page: u32, per_page: u32, ) -> Result<Page<Issue>, ApiError>
One page of search results.
Tracker reports the total in X-Total-Count. When it does not, the page
still has to be honest about whether more exists, which is why
Page::has_more falls back to “a full page probably is not the last”.
Sourcepub async fn count(&self, query: &str) -> Result<u64, ApiError>
pub async fn count(&self, query: &str) -> Result<u64, ApiError>
How many issues match, without fetching any of them.
Sourcepub async fn create_issue(&self, body: &Value) -> Result<Issue, ApiError>
pub async fn create_issue(&self, body: &Value) -> Result<Issue, ApiError>
POST /v3/issues/ — create an issue, returning it normalised.
Sourcepub async fn update_issue(
&self,
key: &str,
body: &Value,
) -> Result<Issue, ApiError>
pub async fn update_issue( &self, key: &str, body: &Value, ) -> Result<Issue, ApiError>
PATCH /v3/issues/{key} — change fields.
Sourcepub async fn add_comment(
&self,
key: &str,
text: &str,
) -> Result<Comment, ApiError>
pub async fn add_comment( &self, key: &str, text: &str, ) -> Result<Comment, ApiError>
POST /v3/issues/{key}/comments — add a comment.
Sourcepub async fn update_comment(
&self,
key: &str,
id: &str,
text: &str,
) -> Result<Comment, ApiError>
pub async fn update_comment( &self, key: &str, id: &str, text: &str, ) -> Result<Comment, ApiError>
Rewrite a comment that is already there.
Tracker keeps no history of the previous text and shows the comment as edited, so this replaces rather than appends: the old wording is gone.
Sourcepub async fn delete_comment(&self, key: &str, id: &str) -> Result<(), ApiError>
pub async fn delete_comment(&self, key: &str, id: &str) -> Result<(), ApiError>
Remove a comment.
Sourcepub async fn update_worklog(
&self,
key: &str,
id: &str,
body: &Value,
) -> Result<Worklog, ApiError>
pub async fn update_worklog( &self, key: &str, id: &str, body: &Value, ) -> Result<Worklog, ApiError>
Correct a worklog entry that is already recorded.
Sourcepub async fn worklogs(&self, key: &str) -> Result<Vec<Worklog>, ApiError>
pub async fn worklogs(&self, key: &str) -> Result<Vec<Worklog>, ApiError>
GET /v3/issues/{key}/worklog — every entry, oldest first.
Sourcepub async fn add_worklog(
&self,
key: &str,
body: &Value,
) -> Result<Worklog, ApiError>
pub async fn add_worklog( &self, key: &str, body: &Value, ) -> Result<Worklog, ApiError>
POST /v3/issues/{key}/worklog — record time spent.
Sourcepub async fn delete_worklog(&self, key: &str, id: &str) -> Result<(), ApiError>
pub async fn delete_worklog(&self, key: &str, id: &str) -> Result<(), ApiError>
DELETE /v3/issues/{key}/worklog/{id}.
Sourcepub async fn checklist(&self, key: &str) -> Result<Vec<ChecklistItem>, ApiError>
pub async fn checklist(&self, key: &str) -> Result<Vec<ChecklistItem>, ApiError>
GET /v3/issues/{key}/checklistItems.
Sourcepub async fn add_checklist_item(
&self,
key: &str,
body: &Value,
) -> Result<Vec<ChecklistItem>, ApiError>
pub async fn add_checklist_item( &self, key: &str, body: &Value, ) -> Result<Vec<ChecklistItem>, ApiError>
POST /v3/issues/{key}/checklistItems — add a line.
Tracker answers with the whole issue rather than the item, so the list
comes back out of the issue’s own checklistItems.
Sourcepub async fn update_checklist_item(
&self,
key: &str,
id: &str,
body: &Value,
) -> Result<Vec<ChecklistItem>, ApiError>
pub async fn update_checklist_item( &self, key: &str, id: &str, body: &Value, ) -> Result<Vec<ChecklistItem>, ApiError>
PATCH /v3/issues/{key}/checklistItems/{id} — tick, untick or reword.
Sourcepub async fn delete_checklist_item(
&self,
key: &str,
id: &str,
) -> Result<(), ApiError>
pub async fn delete_checklist_item( &self, key: &str, id: &str, ) -> Result<(), ApiError>
DELETE /v3/issues/{key}/checklistItems/{id}.
Sourcepub async fn add_link(
&self,
key: &str,
relationship: &str,
other: &str,
) -> Result<(), ApiError>
pub async fn add_link( &self, key: &str, relationship: &str, other: &str, ) -> Result<(), ApiError>
POST /v3/issues/{key}/links — link two issues.
Sourcepub async fn delete_link(&self, key: &str, id: &str) -> Result<(), ApiError>
pub async fn delete_link(&self, key: &str, id: &str) -> Result<(), ApiError>
DELETE /v3/issues/{key}/links/{id}.
Sourcepub async fn transitions(&self, key: &str) -> Result<Vec<Transition>, ApiError>
pub async fn transitions(&self, key: &str) -> Result<Vec<Transition>, ApiError>
Transitions available from the issue’s current status.
Sourcepub async fn execute_transition(
&self,
key: &str,
transition: &str,
body: &Value,
) -> Result<(), ApiError>
pub async fn execute_transition( &self, key: &str, transition: &str, body: &Value, ) -> Result<(), ApiError>
Perform a transition.
Sourcepub async fn entities(
&self,
kind: &str,
input: Option<&str>,
page: u32,
per_page: u32,
) -> Result<Page<Entity>, ApiError>
pub async fn entities( &self, kind: &str, input: Option<&str>, page: u32, per_page: u32, ) -> Result<Page<Entity>, ApiError>
Search projects, portfolios or goals.
The entity endpoints answer with their own envelope (values, hits,
pages) rather than the header-based totals the issue endpoints use, so
the page is assembled from the body here.
Sourcepub async fn entities_in(
&self,
parent: &str,
page: u32,
per_page: u32,
) -> Result<Page<Entity>, ApiError>
pub async fn entities_in( &self, parent: &str, page: u32, per_page: u32, ) -> Result<Page<Entity>, ApiError>
What a portfolio contains: the portfolios and projects under it.
Two requests, because the entity endpoints are typed and containment is
not: a portfolio holds both. The tally sums the two totals, so shown N of M is the real count even though a page is a page of each.
Sourcepub async fn entity(&self, kind: &str, id: &str) -> Result<Entity, ApiError>
pub async fn entity(&self, kind: &str, id: &str) -> Result<Entity, ApiError>
One project, portfolio or goal, by the id the entity endpoints use.
Sourcepub async fn attachments(&self, key: &str) -> Result<Vec<Attachment>, ApiError>
pub async fn attachments(&self, key: &str) -> Result<Vec<Attachment>, ApiError>
The attachments of an issue.
Sourcepub async fn download(&self, url: &str) -> Result<Vec<u8>, ApiError>
pub async fn download(&self, url: &str) -> Result<Vec<u8>, ApiError>
Download an attachment’s bytes.
The download URL comes out of the payload, which means it is supplied by
the server rather than chosen by us. It is checked against the configured
API host before being followed: a crafted content URL must not be able
to send this client, carrying its OAuth header, to somewhere else.
Sourcepub async fn upload(
&self,
key: &str,
filename: &str,
bytes: Vec<u8>,
) -> Result<Attachment, ApiError>
pub async fn upload( &self, key: &str, filename: &str, bytes: Vec<u8>, ) -> Result<Attachment, ApiError>
Upload a file to an issue.
Sourcepub async fn queues(&self) -> Result<Vec<Queue>, ApiError>
pub async fn queues(&self) -> Result<Vec<Queue>, ApiError>
Queues visible to the active profile.
Tracker paginates this endpoint; the ceiling is deliberately generous because “how many queues can I see” is a question with a small answer, and a second page here would be surprising.
Sourcepub async fn worklog_search(
&self,
who: Option<&str>,
since: Option<&str>,
until: Option<&str>,
per_page: u32,
) -> Result<Vec<Worklog>, ApiError>
pub async fn worklog_search( &self, who: Option<&str>, since: Option<&str>, until: Option<&str>, per_page: u32, ) -> Result<Vec<Worklog>, ApiError>
Worklog entries across the whole organisation.
createdBy takes a login or a uid and not me: Tracker reads it as
a login and answers 422 saying no such user exists. Resolving me is
the caller’s job, with one extra request to myself.
Sourcepub async fn move_issue(
&self,
key: &str,
queue: &str,
keep_fields: bool,
initial_status: bool,
) -> Result<Issue, ApiError>
pub async fn move_issue( &self, key: &str, queue: &str, keep_fields: bool, initial_status: bool, ) -> Result<Issue, ApiError>
Move an issue to another queue.
The issue keeps its identity and loses its name: PROJ-42 becomes
OTHER-17, and there is no request that undoes it. Tracker drops fields
the target queue does not define unless moveAllFields says otherwise,
so that choice is the caller’s rather than a default we picked for them.
Sourcepub async fn changelog(
&self,
key: &str,
per_page: u32,
) -> Result<Vec<Change>, ApiError>
pub async fn changelog( &self, key: &str, per_page: u32, ) -> Result<Vec<Change>, ApiError>
What changed on an issue, newest last.
Tracker pages this with an opaque cursor rather than page numbers, and the cursor is only worth spending when somebody asks for more than the first page — which nobody has yet. So this asks for one page, and the caller says how big.
Sourcepub async fn queue_versions(&self, key: &str) -> Result<Vec<Version>, ApiError>
pub async fn queue_versions(&self, key: &str) -> Result<Vec<Version>, ApiError>
The versions a queue defines.
This is what an issue’s fixVersions refers to; without it that field
is an id with no meaning.
The tags in use in a queue.
Sourcepub async fn queue_automation(&self, key: &str) -> Result<Automation, ApiError>
pub async fn queue_automation(&self, key: &str) -> Result<Automation, ApiError>
Everything that changes issues in a queue on its own.
Three requests, and a refusal of one of them is an answer rather than a failure: triggers need queue-owner rights, so a member of the queue gets two sections and Tracker’s own words about the third. All three failing is a different thing — a queue that is not there, or a token that is not allowed — and is reported as the error it is.
Sourcepub async fn dictionary(
&self,
kind: Dictionary,
) -> Result<Vec<DictEntry>, ApiError>
pub async fn dictionary( &self, kind: Dictionary, ) -> Result<Vec<DictEntry>, ApiError>
One of the four organisation-wide dictionaries.
Small and unpaged — the largest of the four is statuses, in the dozens — so this asks for the whole thing and says nothing about pages.
Sourcepub async fn users(
&self,
page: u32,
per_page: u32,
) -> Result<Page<Person>, ApiError>
pub async fn users( &self, page: u32, per_page: u32, ) -> Result<Page<Person>, ApiError>
One page of the organisation’s directory.
Paged, unlike the dictionaries: an organisation has as many people in it as it has people, and the one this was written against already answers with a three-figure total.
Sourcepub async fn user(&self, who: &str) -> Result<Person, ApiError>
pub async fn user(&self, who: &str) -> Result<Person, ApiError>
One person, by login or by uid.
There is no users/me: Tracker answers 404 for it, and myself is the
endpoint that question belongs to.
Sourcepub async fn boards(&self) -> Result<Vec<Board>, ApiError>
pub async fn boards(&self) -> Result<Vec<Board>, ApiError>
Boards visible to the active profile.
Not paginated by the endpoint, and not by us: an organisation has boards in the dozens, not the thousands.
Sourcepub async fn sprints(&self, board: &str) -> Result<Vec<Sprint>, ApiError>
pub async fn sprints(&self, board: &str) -> Result<Vec<Sprint>, ApiError>
The sprints of a board.
A board that cannot have sprints answers with a refusal rather than an empty list, and that refusal is passed through as Tracker worded it: a kanban board having no sprints is Tracker’s answer to the question, not a failure of the command, and inventing an empty list here would hide which of the two happened.
Sourcepub async fn all_sprints(&self) -> Result<Vec<Sprint>, ApiError>
pub async fn all_sprints(&self) -> Result<Vec<Sprint>, ApiError>
Every sprint in the organisation.
board sprints ID needs the board first, and a sprint name is a thing
people say without knowing which board it belongs to. This is the same
records with the board named on each.
Sourcepub async fn queue_local_fields(
&self,
key: &str,
) -> Result<Vec<FieldSpec>, ApiError>
pub async fn queue_local_fields( &self, key: &str, ) -> Result<Vec<FieldSpec>, ApiError>
The fields a queue defines itself.
Not a subset of Self::queue_fields, which lists everything the queue
can use: a local field belongs to the queue, is invisible to the
organisation-wide listing, and cannot be fetched through /v3/fields at
all. So these carry their full definition — what they accept included —
because there is no second command that could answer that for them.
Sourcepub async fn create_entity(
&self,
kind: &str,
fields: &Value,
) -> Result<Entity, ApiError>
pub async fn create_entity( &self, kind: &str, fields: &Value, ) -> Result<Entity, ApiError>
Create a project, portfolio or goal with nothing but a name.
Everything else about an entity is optional, and a command line is not where a portfolio’s description gets written.
Sourcepub async fn delete_entity(&self, kind: &str, id: &str) -> Result<(), ApiError>
pub async fn delete_entity(&self, kind: &str, id: &str) -> Result<(), ApiError>
Delete a project, portfolio or goal.
Entities can be deleted; issues cannot. That asymmetry is why the live suite may write entities and may not write issues without being told a queue to sacrifice.
Sourcepub async fn update_entity(
&self,
kind: &str,
id: &str,
fields: &Value,
version: Option<u64>,
) -> Result<Entity, ApiError>
pub async fn update_entity( &self, kind: &str, id: &str, fields: &Value, version: Option<u64>, ) -> Result<Entity, ApiError>
Change the fields of a project, portfolio or goal.
Quotes the version for the same reason Self::place_entity does: a
write without one lands on top of whatever happened in between.
Sourcepub async fn place_entity(
&self,
kind: &str,
id: &str,
parent: Option<&str>,
version: Option<u64>,
) -> Result<Entity, ApiError>
pub async fn place_entity( &self, kind: &str, id: &str, parent: Option<&str>, version: Option<u64>, ) -> Result<Entity, ApiError>
Put an entity inside a portfolio, or take it out of one.
version is Tracker’s optimistic-concurrency counter and is quoted on
purpose: without it the write lands whatever happened in between, and
with it a portfolio that moved under us answers 412 instead of being
silently overwritten.
Sourcepub async fn queue(&self, key: &str) -> Result<QueueSettings, ApiError>
pub async fn queue(&self, key: &str) -> Result<QueueSettings, ApiError>
One queue and its settings.
Sourcepub async fn queue_blueprint(&self, key: &str) -> Result<Blueprint, ApiError>
pub async fn queue_blueprint(&self, key: &str) -> Result<Blueprint, ApiError>
The parts of a queue that another queue can be built from.
issueTypesConfig pairs each issue type with a workflow and a set of
resolutions, and workflow ids are organisation-specific strings nobody
has memorised. Copying them from a queue that already works is the only
way to create one from a command line without asking for internals.
Sourcepub async fn create_queue(
&self,
body: &Value,
) -> Result<QueueSettings, ApiError>
pub async fn create_queue( &self, body: &Value, ) -> Result<QueueSettings, ApiError>
Create a queue.
Sourcepub async fn fields(&self) -> Result<Vec<QueueField>, ApiError>
pub async fn fields(&self) -> Result<Vec<QueueField>, ApiError>
Every field defined in the organisation, not just one queue’s.
queue fields answers “what can I set on an issue here”; this answers
“what exists at all”, which is the question behind a field that a queue
does not show.
Sourcepub async fn field(&self, key: &str) -> Result<FieldSpec, ApiError>
pub async fn field(&self, key: &str) -> Result<FieldSpec, ApiError>
One field’s definition, by the key queue fields prints.
A local field defined inside one queue is not reachable here — it lives under the queue — and Tracker answers 404 for it, which is the honest answer rather than one worth papering over.
Sourcepub async fn templates(
&self,
kind: TemplateKind,
) -> Result<Vec<Template>, ApiError>
pub async fn templates( &self, kind: TemplateKind, ) -> Result<Vec<Template>, ApiError>
Issue or comment templates.
The path is issueTemplates and commentTemplates; there is no
_templates collection, which is worth writing down because every
plausible guess at one answers 400 or 404.
Sourcepub async fn issue_comments(&self, key: &str) -> Result<Vec<Comment>, ApiError>
pub async fn issue_comments(&self, key: &str) -> Result<Vec<Comment>, ApiError>
The comments of an issue.
Fetched in one generous page: an issue with more than a hundred comments is rare enough that paginating here would cost more in complexity than it saves anyone.
Sourcepub async fn queue_fields(&self, key: &str) -> Result<Vec<QueueField>, ApiError>
pub async fn queue_fields(&self, key: &str) -> Result<Vec<QueueField>, ApiError>
The fields of a queue, including custom ones, as (key, name, type).
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for Client
impl !UnwindSafe for Client
impl Freeze for Client
impl Send for Client
impl Sync for Client
impl Unpin for Client
impl UnsafeUnpin for Client
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);