Skip to main content

Client

Struct Client 

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

A HEY client: one authenticated identity, presenting mail from All Accounts unless derived for one linked account with Client::for_account.

Clients are cheap to clone and share their connection pool, credentials and cache.

Implementations§

Source§

impl Client

Source

pub async fn for_account(&self, account_id: i64) -> Result<Client, Error>

Derives a client that presents mail from one linked account and acts as that account’s user and default sender. The account is checked against the identity first, so a stale or foreign id fails here rather than on the first read. That check goes out through an unscoped client derived from this one: the identity belongs to the whole login, and reading it filtered to an account would leave nothing to check the account against.

Calendar, journal, habits and time tracking belong to the identity, so they read the same through a scoped client.

Source

pub async fn default_sender_id(&self) -> Result<i64, Error>

The sender a message goes out as when the caller names none: the scoped account’s default sender, or the identity’s default sender for All Accounts.

Source

pub async fn account_user_id(&self) -> Result<i64, Error>

The identity’s user in the scoped account, which is what a record is filed under.

Source§

impl Client

Source

pub fn builder(config: Config) -> ClientBuilder

A ClientBuilder for config, at the defaults.

Source

pub fn new( config: Config, provider: impl TokenProvider + 'static, ) -> Result<Client, Error>

Available on crate feature reqwest only.

A client with the default settings and a bearer token, on the HTTP client the SDK ships. Without the reqwest feature there is no such client, and a ClientBuilder with an HttpClient of the application’s own is the way in.

Source

pub fn config(&self) -> &Config

The configuration this client was built from.

Source

pub fn base_url(&self) -> &Url

Where HEY is, with the trailing slash every path is joined to.

Source

pub fn account_id(&self) -> Option<i64>

The linked account this client presents, or None for All Accounts.

Source

pub fn max_pages(&self) -> usize

How many pages a walk reads before it stops.

Source

pub fn operation( &self, route: &'static Route, params: &[&dyn Display], ) -> Operation

Starts a request for one of the modelled routes. Generated service methods call this; reach for it directly only to add headers or query parameters they do not expose.

Source

pub fn request(&self, method: Method, path: impl Into<String>) -> Operation

Starts a request for a path the model does not cover. The path is relative to the base URL and gets the same credentials, .json suffix, account scope and retry treatment as a modelled one.

Source

pub async fn send<T: DeserializeOwned>( &self, operation: Operation, ) -> Result<T, Error>

Sends an operation and decodes its JSON body.

Source

pub async fn send_unit(&self, operation: Operation) -> Result<(), Error>

Sends an operation whose answer carries no body worth reading.

Source

pub async fn send_text(&self, operation: Operation) -> Result<String, Error>

Sends an operation and reads its body as text: the HTML page a route serves no JSON for.

Source

pub async fn send_optional<T: DeserializeOwned>( &self, operation: Operation, ) -> Result<Option<T>, Error>

Sends an operation that answers a status meaning “nothing there” with None.

Source

pub async fn send_page<T: DeserializeOwned>( &self, operation: Operation, ) -> Result<Page<T>, Error>

Sends a paginated read and keeps the cursor HEY answered with.

Source

pub async fn next_page<T: DeserializeOwned>( &self, page: &Page<T>, ) -> Result<Option<Page<T>>, Error>

Reads the page after the given one, or None when HEY named no next page. A Link header pointing off the HEY origin is refused rather than followed. The read announces itself as the operation the first page came from, so a whole walk shows up as one thing rather than as a list read followed by anonymous requests, and it is resent under that operation’s retry policy.

Source

pub async fn each_page<T: DeserializeOwned>( &self, first: Page<T>, visit: impl FnMut(&Page<T>) -> bool, ) -> Result<(), Error>

Reads every page after the first, calling visit with each one. Stops early when visit answers false. A walk that reaches the client’s page limit with pages still to read stops there and says so, as Error::pagination_capped: the pages visited stand, and the caller knows they were not all of them.

Source

pub async fn execute(&self, operation: Operation) -> Result<Response, Error>

Sends an operation: asks the hooks whether it may run, applies credentials and account scope, retries transient failures when the operation is idempotent, resends once after a refreshed 401, and answers a cached body on 304. Non-2xx statuses become errors unless the operation treats them as empty.

Source§

impl Client

Source

pub fn form(&self, method: Method, path: &str) -> Result<Operation, Error>

A request to one of the endpoints HEY serves only as a browser form: the path as the caller wrote it, a browser’s Accept, and the redirect taken for the answer rather than followed.

It is not retried, whatever its method — a form post that may already have gone through is not one to repeat on a timeout or a 503. A 401 is the exception the whole client makes: credentials are refreshed and the request goes out once more, since a request HEY refused for want of a token never reached the write it would repeat.

The model describes none of these paths, so say what the call means with Operation::info before sending it, or the hooks will only hear that something raw went out. crate::services::write_info builds that.

A path that already is a URL is checked before it is taken: HTTPS goes anywhere, plain HTTP only back to the base URL’s own host. That check is what this can fail on.

Source

pub async fn send_form( &self, operation: Operation, ) -> Result<FormResponse, Error>

Sends a form request and reads the redirect it answered with.

A failure keeps the code, hint and request id HEY answered with. Go flattens every status but 401 into a bare “Form request failed (HTTP 503)”, which loses the request id support would look the call up by and tells a caller nothing it could act on; a 503 here still reads as the retryable API error it is.

Source§

impl Client

Source

pub fn attachments(&self) -> Attachments<'_>

Source

pub fn boxes(&self) -> Boxes<'_>

Source

pub fn bulk_replies(&self) -> BulkReplies<'_>

Source

pub fn calendar_events(&self) -> CalendarEvents<'_>

Source

pub fn calendar_periods(&self) -> CalendarPeriods<'_>

Source

pub fn calendar_todos(&self) -> CalendarTodos<'_>

Source

pub fn calendars(&self) -> Calendars<'_>

Source

pub fn clearances(&self) -> Clearances<'_>

Source

pub fn clips(&self) -> Clips<'_>

Source

pub fn collections(&self) -> Collections<'_>

Source

pub fn contacts(&self) -> Contacts<'_>

Source

pub fn designations(&self) -> Designations<'_>

Source

pub fn entries(&self) -> Entries<'_>

Source

pub fn extenzions(&self) -> Extenzions<'_>

Source

pub fn folders(&self) -> Folders<'_>

Source

pub fn habits(&self) -> Habits<'_>

Source

pub fn identity(&self) -> Identity<'_>

Source

pub fn journal(&self) -> Journal<'_>

Source

pub fn messages(&self) -> Messages<'_>

Source

pub fn postings(&self) -> Postings<'_>

Source

pub fn publications(&self) -> Publications<'_>

Source

pub fn search(&self) -> Search<'_>

Source

pub fn snippets(&self) -> Snippets<'_>

Source

pub fn stickies(&self) -> Stickies<'_>

Source

pub fn time_tracks(&self) -> TimeTracks<'_>

Source

pub fn topics(&self) -> Topics<'_>

Source

pub fn workflows(&self) -> Workflows<'_>

Source§

impl Client

Source

pub async fn get_all(&self, path: &str) -> Result<Vec<Value>, Error>

Reads a paginated path to its end and hands back the items of every page as one list. Each page has to decode as a JSON array. Use this for the paths the model does not cover; a modelled read walks with Client::each_page, which keeps the records typed. A walk that reaches the client’s page limit with pages still to read is an error, Error::pagination_capped, rather than a shorter list that looks complete.

Source

pub async fn get_all_with_limit( &self, path: &str, limit: usize, ) -> Result<Vec<Value>, Error>

Reads a paginated path until limit items are in hand, or to its end when limit is zero. The last page is trimmed to land on exactly limit.

Source

pub async fn follow_pagination( &self, first: &Response, first_page_count: usize, limit: usize, ) -> Result<Vec<Value>, Error>

Reads the pages after one already in hand, and hands back their items. Say how many the first page held as first_page_count, so a limit counts the whole walk; limit of zero reads to the end.

A Response names no route, so the pages are read on the client’s own retry settings, as Client::get_all reads them. A modelled read walks on with Client::next_page or Client::each_page, which keep its policy.

Source§

impl Client

Source

pub async fn get(&self, path: &str) -> Result<Response, Error>

Reads a path the model does not cover.

Source

pub async fn get_html(&self, path: &str) -> Result<Response, Error>

Reads the HTML representation, for the pages HEY serves no JSON for.

Source

pub async fn get_csv(&self, path: &str) -> Result<Response, Error>

Reads an export, which HEY streams as a file rather than a document.

Source

pub fn csv(&self, path: &str) -> Result<Operation, Error>

A request for one of the exports HEY streams as a file. This and Client::get_csv stand to each other as Client::form does to Client::post_form: a call that has something to say about itself builds the operation here and gives it an Operation::info before sending it.

Source

pub async fn get_blob(&self, path: &str) -> Result<Response, Error>

Reads a file whole. Client::download_blob writes one out as it arrives instead, for a file too large to want in memory.

Source

pub async fn download_blob( &self, path: &str, destination: &mut (impl AsyncWrite + Unpin), ) -> Result<(u64, HeaderMap), Error>

Writes a file to destination as it arrives, and answers how many bytes went and what headers came with them. Nothing is read into memory, and nothing is resent: once bytes are on their way to the destination a second attempt would double them.

Source

pub async fn post( &self, path: &str, body: &impl Serialize, ) -> Result<Response, Error>

Posts a JSON body to a path the model does not cover.

Source

pub async fn post_mutation( &self, path: &str, body: &impl Serialize, ) -> Result<Response, Error>

Posts to an endpoint that may answer with something other than JSON.

Source

pub async fn put( &self, path: &str, body: &impl Serialize, ) -> Result<Response, Error>

Puts a JSON body to a path the model does not cover.

Source

pub async fn patch( &self, path: &str, body: &impl Serialize, ) -> Result<Response, Error>

Patches a path the model does not cover with a JSON body.

Source

pub async fn patch_mutation( &self, path: &str, body: &impl Serialize, ) -> Result<Response, Error>

Patches an endpoint that may answer with something other than JSON.

Source

pub async fn delete(&self, path: &str) -> Result<Response, Error>

Deletes at a path the model does not cover.

Source

pub async fn post_form( &self, path: &str, fields: &[(&str, &str)], ) -> Result<FormResponse, Error>

Posts a form the way a browser would, and captures the redirect HEY answers with rather than following it. FormResponse::extract_id reads the created record’s id out of that redirect.

This and the three below are Client::form and Client::send_form together. A call that has something to say about itself builds the operation with those two instead, and gives it an Operation::info on the way.

Source

pub async fn patch_form( &self, path: &str, fields: &[(&str, &str)], ) -> Result<FormResponse, Error>

Patches through the form endpoint, the way a browser’s edit form would.

Source

pub async fn delete_form(&self, path: &str) -> Result<FormResponse, Error>

Deletes through the form endpoint, which answers a redirect. The request carries no body, and so no content type either.

Source

pub async fn post_multipart( &self, path: &str, content_type: String, body: Bytes, ) -> Result<FormResponse, Error>

Posts a multipart body the caller assembled, for the endpoints that take a file.

Source§

impl Client

Source

pub fn world(&self) -> World<'_>

The HEY World service.

Trait Implementations§

Source§

impl Clone for Client

Source§

fn clone(&self) -> Client

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

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<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
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> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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<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