#[non_exhaustive]pub struct SessionClient { /* private fields */ }Expand description
A JmapClient bound to a JMAP session.
Obtain via JmapMailExt::with_mail_session.
All JMAP Mail methods are available on this type without needing to pass
&Session on every call.
§Session lifecycle
SessionClient captures the Session at construction time. After
re-fetching the session via JmapClient::fetch_session, construct a new
SessionClient with the updated session. Reusing a stale SessionClient
after session expiry will result in unknownAccount or similar errors
from the server.
Clone is derived because JmapClient is itself cheap-to-clone (it
already implements Clone and with_mail_session clones one
internally), enabling parallel-task fan-out with one bound session.
Debug is implemented manually to redact the inner JmapClient (which
holds an HTTP client and is intentionally not Debug in
jmap-base-client); only the Session is shown. This lets callers
embed a SessionClient in a #[derive(Debug)] struct without manual
impls of their own.
§Thread safety
SessionClient is Send + Sync. Both
jmap_base_client::JmapClient (backed by reqwest::Client) and
jmap_base_client::Session (plain serde-derived data) are
Send + Sync per jmap-base-client’s contract, so this type can be
shared across async tasks via Arc<SessionClient> or cloned for
per-task ownership (Clone is cheap — see above).
A Send + Sync regression in a future jmap-base-client release
would be a major-version-breaking change for this crate. A
compile-time assertion in tests/ guards against the regression
landing silently — see _assert_session_client_send_sync in
methods/mod.rs.
Implementations§
Source§impl SessionClient
impl SessionClient
Sourcepub async fn email_get(
&self,
ids: Option<&[Id]>,
properties: Option<&[&str]>,
params: Option<EmailGetParams>,
) -> Result<GetResponse<Email>, ClientError>
pub async fn email_get( &self, ids: Option<&[Id]>, properties: Option<&[&str]>, params: Option<EmailGetParams>, ) -> Result<GetResponse<Email>, ClientError>
Fetch Email objects by IDs (RFC 8621 §4.1.8 — Email/get).
If ids is None, the server returns all Emails for the account,
SUBJECT TO the server’s maxObjectsInGet cap (RFC 8620 §5.1).
For production use, scope the result set via the corresponding
/query method first and pass explicit ids here to avoid
requestTooLarge errors when the account holds more objects
than the cap.
Pass properties: None to return all fields.
Pass params: None to use server defaults for body-fetch options.
§Errors
ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.ClientError::InvalidArgumentifparamsisSomeand serializing it to JSON fails (pathological conditions only — allocation failure, or a vendor value inparams.extrathat itself fails to serialize).- Any transport / protocol variant returned by
JmapClient::call:Http,Parse,AuthFailed,MethodError(wraps RFC 8620 §3.6.2 method-level errors such asaccountNotFound,invalidArguments,serverFail),MethodNotFound,ResponseTooLarge, orUnexpectedResponse.
Sourcepub async fn email_changes(
&self,
since_state: &State,
max_changes: Option<u64>,
) -> Result<ChangesResponse, ClientError>
pub async fn email_changes( &self, since_state: &State, max_changes: Option<u64>, ) -> Result<ChangesResponse, ClientError>
Fetch changes to Email objects since since_state (RFC 8621 §4.2 — Email/changes).
If has_more_changes is true in the response, call again with new_state
as since_state until the flag is false.
§max_changes spec magic-values (RFC 8620 §5.2)
Noneomits the wire field and lets the server apply its default cap.Some(0)is wire-legal and means “no client limit”; the server may still apply its own cap. This is distinct fromNone:Nonesays “I haven’t expressed a preference”,Some(0)says “I want as many entries as the server is willing to return in one round-trip”.Some(n)withn > 0requests at mostnentries; the server may return fewer.
§Errors
ClientError::InvalidArgumentifsince_stateis the empty string (defence-in-depth —Stateconstructed viaState::fromaccepts empty strings, but an emptysinceStateis never useful and would otherwise generate a wasted round-trip).ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::email_get.
Sourcepub async fn email_set(
&self,
create: Option<Value>,
update: Option<HashMap<Id, PatchObject>>,
destroy: Option<Vec<Id>>,
if_in_state: Option<&State>,
) -> Result<SetResponse<Email>, ClientError>
pub async fn email_set( &self, create: Option<Value>, update: Option<HashMap<Id, PatchObject>>, destroy: Option<Vec<Id>>, if_in_state: Option<&State>, ) -> Result<SetResponse<Email>, ClientError>
Create, update, or destroy Email objects (RFC 8621 §4.3 — Email/set).
Pass create, update, and/or destroy as needed. All three are
optional; pass None to omit any operation from the request.
Pass if_in_state: Some(&state) to use an optimistic-concurrency guard.
update is Option<HashMap<Id, PatchObject>> (RFC 8620 §5.3). Wire
format is unchanged from a plain JSON object because PatchObject
is #[serde(transparent)]; the typed parameter binds the JSON Pointer
key + null-leaf removal contract to the type system.
§Errors
ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.ClientError::InvalidArgumentifupdateisSomeandserde_json::to_valuefails on the patch map. In practice this happens only under pathological conditions (allocation failure on a very largeHashMap, or aPatchObjectwhose JSON tree exceedsserde_json’s recursion limit). The size ofupdateis otherwise bounded only by available memory; the wire request is buffered by the HTTP client (reqwest::RequestBuilder::jsoncallsserde_json::to_vecupfront), so the transient peak holds the sourceHashMap, the intermediateserde_json::Valuetree, and the serializedVec<u8>body simultaneously — roughly 3-4× theHashMap’s in-memory size. Callers dealing with thousands of patches per call may prefer to batch.- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::email_get.
Sourcepub async fn email_query(
&self,
filter: Option<Value>,
sort: Option<Value>,
position: Option<u64>,
limit: Option<u64>,
collapse_threads: Option<bool>,
) -> Result<QueryResponse, ClientError>
pub async fn email_query( &self, filter: Option<Value>, sort: Option<Value>, position: Option<u64>, limit: Option<u64>, collapse_threads: Option<bool>, ) -> Result<QueryResponse, ClientError>
Query Email IDs with optional filter and sort (RFC 8621 §4.4 — Email/query).
Pass filter: None and sort: None to return all Emails with
server-default ordering. Use position and limit for pagination.
Pass collapse_threads: Some(true) to return at most one email per thread.
§Numeric parameter spec magic-values (RFC 8620 §5.5)
position: Some(0)selects the first item (zero-indexed); the spec also accepts negative values, butu64does not represent them — passNoneto omit and use the server default of0.limit: Some(0)is wire-legal but means “server’s default cap”, NOT “zero results”; the server is free to return its default page size. PassNoneto omit (server applies its default), orSome(n)withn > 0for an explicit cap.
§Errors
ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::email_get. RFC 8620 §5.5 defines additional method-level errors specific to /query (anchorNotFound,unsupportedFilter,unsupportedSort,tooManyChanges); they surface here asMethodErrorwith the correspondingerror_typestring.
Sourcepub async fn email_query_changes(
&self,
since_query_state: &State,
max_changes: Option<u64>,
collapse_threads: Option<bool>,
filter: Option<Value>,
sort: Option<Value>,
up_to_id: Option<&Id>,
calculate_total: Option<bool>,
) -> Result<QueryChangesResponse, ClientError>
pub async fn email_query_changes( &self, since_query_state: &State, max_changes: Option<u64>, collapse_threads: Option<bool>, filter: Option<Value>, sort: Option<Value>, up_to_id: Option<&Id>, calculate_total: Option<bool>, ) -> Result<QueryChangesResponse, ClientError>
Fetch query-result changes for Email since since_query_state
(RFC 8621 §4.5 — Email/queryChanges).
filter and sort MUST match the filter / sort passed to the
original Email/query call that returned since_query_state —
RFC 8620 §5.6 is explicit that the server uses them to compute
which entries entered or left the result set. Omitting them when
the original query had a non-trivial filter or sort tells the
server “the original query had no filter and default sort”, which
gives the wrong added/removed deltas (or cannotCalculateChanges).
up_to_id is the highest-index id the client has cached
(RFC 8620 §5.6); the server may use it to omit changes past that
point when both filter and sort are on immutable properties.
calculate_total requests the new total result count.
max_changes follows the same magic-value semantics as
Self::email_changes.
§Errors
ClientError::InvalidArgumentifsince_query_stateis the empty string (defence-in-depth empty-state guard; seeSelf::email_changes).ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::email_get. RFC 8620 §5.6 also definescannotCalculateChanges(returned when the server cannot honour the request given the supplied filter / sort); it surfaces asMethodError.
Sourcepub async fn email_copy(
&self,
params: EmailCopyParams,
create: Value,
) -> Result<SetResponse<Email>, ClientError>
pub async fn email_copy( &self, params: EmailCopyParams, create: Value, ) -> Result<SetResponse<Email>, ClientError>
Copy Emails from another account (RFC 8621 §4.7 — Email/copy).
params carries fromAccountId and optional destroy-after-copy flags.
create is a map of creation keys to partial Email objects (with new
mailboxIds etc.) as described in RFC 8621 §4.7.
§Cross-account error space (RFC 8620 §5.4 + RFC 8621 §4.7)
Email/copy is the ONLY method in this crate that crosses
account boundaries, and it has a method-specific error space
that ordinary Email/set does not. The following codes surface
as ClientError::MethodError
with the corresponding error_type string:
fromAccountNotFound—from_account_idis not an account the user can access.fromAccountNotSupportedByMethod— the source account does not support the JMAP Mail capability.stateMismatch—destroy_from_if_in_statedid not match the current state of Email on the source account.tooManyCopies— server-defined cap on copies-per-request exceeded.tooManyEmails— server-defined cap on emails-per-copy exceeded.anchorNotFound— RFC 8620 §5.4 reserves this for#-prefixed result references that cannot be resolved.
Per-entry failures (one per creation key in create) appear in
SetResponse::not_created as SetError
values, NOT as method-level errors. Common per-entry codes
include invalidProperties, notFound (when the source email
id does not exist), overQuota, and alreadyExists.
§Errors
ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail. (The destination account is the session’s primary mail account; the source account is thefrom_account_idargument.)- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::email_get. - The /copy-specific method-level errors listed in the
“Cross-account error space” section above, surfaced as
MethodError.
Sourcepub async fn email_import(
&self,
emails: &HashMap<String, EmailImportInput<'_>>,
if_in_state: Option<&State>,
) -> Result<EmailImportResponse, ClientError>
pub async fn email_import( &self, emails: &HashMap<String, EmailImportInput<'_>>, if_in_state: Option<&State>, ) -> Result<EmailImportResponse, ClientError>
Import raw RFC 5322 messages into the account (RFC 8621 §4.8 — Email/import).
Each entry in emails maps a caller-chosen creation id to an
EmailImportInput referencing a previously uploaded blob and the
target mailbox(es). The blob must have been uploaded via the standard
blob-upload mechanism on jmap-base-client before calling this method.
At least one mailbox id is required per RFC 8621 §4.8; the empty-set
case is rejected client-side as InvalidArgument. An empty emails
map is also rejected — a no-op import is never useful and would
generate a round-trip with no successful creations.
Pass if_in_state: Some(&state) for an optimistic-concurrency guard
against the Email object state (RFC 8621 §4.8 returns stateMismatch
if the supplied state does not match).
Per-creation failures appear in EmailImportResponse::not_created
as super::SetError values; possible error codes include alreadyExists
(with an existingId extra field), invalidProperties, overQuota,
and invalidEmail.
§Errors
ClientError::InvalidArgumentifemailsis empty, if any entry’smailbox_idsis empty (RFC 8621 §4.8 requires at least one mailbox per import), or if serializing theemailsmap fails (pathological conditions only — allocation failure, or a vendor value inEmailImportInput.extrathat itself fails to serialize).ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::email_get. RFC 8621 §4.8 definesmaxQuotaReached,fromAccountNotFound, andstateMismatch(the last whenif_in_statedoes not match); they surface asMethodError. Per-creation failures (e.g.alreadyExists,invalidEmail) do NOT surface asErr— they appear inEmailImportResponse::not_created.
Sourcepub async fn email_parse(
&self,
blob_ids: &[Id],
params: Option<EmailParseParams>,
) -> Result<EmailParseResponse, ClientError>
pub async fn email_parse( &self, blob_ids: &[Id], params: Option<EmailParseParams>, ) -> Result<EmailParseResponse, ClientError>
Parse uploaded blobs as RFC 5322 messages without importing them (RFC 8621 §4.9 — Email/parse).
Returns Email objects derived from each blob. Per RFC 8621 §4.9 the
returned Emails have id, mailboxIds, keywords, and receivedAt
set to null (the messages are not in the mail store); threadId
MAY be present if the server can predict the assignment.
Pass params: None to use server defaults for properties and body
fetching. The set of properties returned defaults to the spec-listed
header/body fields documented in RFC 8621 §4.9.
Empty blob_ids is rejected as InvalidArgument — a no-op parse
round-trip is never useful.
§Errors
ClientError::InvalidArgumentifblob_idsis empty, or ifparamsisSomeand serializing it to JSON fails (pathological conditions only — allocation failure, or a vendor value inparams.extrathat itself fails to serialize).ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::email_get.
Source§impl SessionClient
impl SessionClient
Sourcepub async fn identity_get(
&self,
ids: Option<&[Id]>,
properties: Option<&[&str]>,
) -> Result<GetResponse<Identity>, ClientError>
pub async fn identity_get( &self, ids: Option<&[Id]>, properties: Option<&[&str]>, ) -> Result<GetResponse<Identity>, ClientError>
Fetch Identity objects by IDs (RFC 8621 §6.1 — Identity/get).
If ids is None, the server returns all Identities for the account,
SUBJECT TO the server’s maxObjectsInGet cap (RFC 8620 §5.1).
For production use, scope the result set via the corresponding
/query method first and pass explicit ids here to avoid
requestTooLarge errors when the account holds more objects
than the cap.
Pass properties: None to return all fields.
§Errors
ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail. (Identity/* uses theurn:ietf:params:jmap:submissioncapability for itsusingarray but is keyed on the mail primary account.)- Any transport / protocol variant returned by
JmapClient::call:Http,Parse,AuthFailed,MethodError(wraps RFC 8620 §3.6.2 method-level errors such asaccountNotFound,invalidArguments,serverFail),MethodNotFound,ResponseTooLarge, orUnexpectedResponse.
Sourcepub async fn identity_changes(
&self,
since_state: &State,
max_changes: Option<u64>,
) -> Result<ChangesResponse, ClientError>
pub async fn identity_changes( &self, since_state: &State, max_changes: Option<u64>, ) -> Result<ChangesResponse, ClientError>
Fetch changes to Identity objects since since_state (RFC 8621 §6.2 — Identity/changes).
max_changes follows the same RFC 8620 §5.2 magic-value semantics
as SessionClient::email_changes:
None lets the server apply its default cap, Some(0) means
“no client limit”, Some(n>0) requests at most n entries.
§Errors
ClientError::InvalidArgumentifsince_stateis the empty string (defence-in-depth —Stateconstructed viaState::fromaccepts empty strings, but an emptysinceStateis never useful and would otherwise generate a wasted round-trip).ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::identity_get.
Sourcepub async fn identity_set(
&self,
create: Option<Value>,
update: Option<HashMap<Id, PatchObject>>,
destroy: Option<Vec<Id>>,
) -> Result<SetResponse<Identity>, ClientError>
pub async fn identity_set( &self, create: Option<Value>, update: Option<HashMap<Id, PatchObject>>, destroy: Option<Vec<Id>>, ) -> Result<SetResponse<Identity>, ClientError>
Create, update, or destroy Identity objects (RFC 8621 §6.3 — Identity/set).
Pass create, update, and/or destroy as needed. Pass None to omit.
update is Option<HashMap<Id, PatchObject>> (RFC 8620 §5.3). Wire
format is unchanged from a plain JSON object because PatchObject
is #[serde(transparent)]; the typed parameter binds the JSON Pointer
key + null-leaf removal contract to the type system.
§Errors
ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.ClientError::InvalidArgumentifupdateisSomeandserde_json::to_valuefails on the patch map (pathological conditions only; seeSelf::email_setfor the memory-cost discussion that applies identically here).- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::identity_get.
Source§impl SessionClient
impl SessionClient
Sourcepub async fn mailbox_get(
&self,
ids: Option<&[Id]>,
properties: Option<&[&str]>,
) -> Result<GetResponse<Mailbox>, ClientError>
pub async fn mailbox_get( &self, ids: Option<&[Id]>, properties: Option<&[&str]>, ) -> Result<GetResponse<Mailbox>, ClientError>
Fetch Mailbox objects by IDs (RFC 8621 §2.1 — Mailbox/get).
If ids is None, the server returns all Mailboxes for the account,
SUBJECT TO the server’s maxObjectsInGet cap (RFC 8620 §5.1).
For production use, scope the result set via the corresponding
/query method first and pass explicit ids here to avoid
requestTooLarge errors when the account holds more objects
than the cap.
Pass properties: None to return all fields.
§Errors
ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.- Any transport / protocol variant returned by
JmapClient::call:Http,Parse,AuthFailed,MethodError(wraps RFC 8620 §3.6.2 method-level errors such asaccountNotFound,invalidArguments,serverFail),MethodNotFound,ResponseTooLarge, orUnexpectedResponse.
Sourcepub async fn mailbox_changes(
&self,
since_state: &State,
max_changes: Option<u64>,
) -> Result<ChangesResponse, ClientError>
pub async fn mailbox_changes( &self, since_state: &State, max_changes: Option<u64>, ) -> Result<ChangesResponse, ClientError>
Fetch changes to Mailbox objects since since_state (RFC 8621 §2.2 — Mailbox/changes).
max_changes follows the same RFC 8620 §5.2 magic-value semantics
as Self::email_changes: None lets the server apply its
default cap, Some(0) means “no client limit”, Some(n>0)
requests at most n entries.
§Errors
ClientError::InvalidArgumentifsince_stateis the empty string (defence-in-depth —Stateconstructed viaState::fromaccepts empty strings, but an emptysinceStateis never useful and would otherwise generate a wasted round-trip).ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::mailbox_get.
Sourcepub async fn mailbox_set(
&self,
create: Option<Value>,
update: Option<HashMap<Id, PatchObject>>,
destroy: Option<Vec<Id>>,
params: Option<MailboxSetParams>,
) -> Result<SetResponse<Mailbox>, ClientError>
pub async fn mailbox_set( &self, create: Option<Value>, update: Option<HashMap<Id, PatchObject>>, destroy: Option<Vec<Id>>, params: Option<MailboxSetParams>, ) -> Result<SetResponse<Mailbox>, ClientError>
Create, update, or destroy Mailbox objects (RFC 8621 §2.5 — Mailbox/set).
Pass create, update, and/or destroy as needed. Pass None to omit.
Pass params: Some(MailboxSetParams { on_destroy_remove_emails: Some(true) })
to allow destroying a non-empty mailbox.
update is Option<HashMap<Id, PatchObject>> (RFC 8620 §5.3). Wire
format is unchanged from a plain JSON object because PatchObject
is #[serde(transparent)]; the typed parameter binds the JSON Pointer
key + null-leaf removal contract to the type system.
§Errors
ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.ClientError::InvalidArgumentifupdateisSomeandserde_json::to_valuefails on the patch map (pathological conditions only; seeSelf::email_setfor the memory-cost discussion that applies identically here).- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::mailbox_get.
Sourcepub async fn mailbox_query(
&self,
filter: Option<Value>,
sort: Option<Value>,
position: Option<u64>,
limit: Option<u64>,
) -> Result<QueryResponse, ClientError>
pub async fn mailbox_query( &self, filter: Option<Value>, sort: Option<Value>, position: Option<u64>, limit: Option<u64>, ) -> Result<QueryResponse, ClientError>
Query Mailbox IDs with optional filter and sort (RFC 8621 §2.3 — Mailbox/query).
Pass filter: None and sort: None to return all Mailboxes with
server-default ordering. Use position and limit for pagination.
position and limit follow the same RFC 8620 §5.5 magic-value
semantics as Self::email_query: position: Some(0) is the
first item (zero-indexed); limit: Some(0) means “server’s
default cap”, NOT “zero results”.
§Errors
ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::mailbox_get. RFC 8620 §5.5 defines additional /query method-level errors (anchorNotFound,unsupportedFilter,unsupportedSort,tooManyChanges) that surface asMethodError.
Sourcepub async fn mailbox_query_changes(
&self,
since_query_state: &State,
max_changes: Option<u64>,
filter: Option<Value>,
sort: Option<Value>,
up_to_id: Option<&Id>,
calculate_total: Option<bool>,
) -> Result<QueryChangesResponse, ClientError>
pub async fn mailbox_query_changes( &self, since_query_state: &State, max_changes: Option<u64>, filter: Option<Value>, sort: Option<Value>, up_to_id: Option<&Id>, calculate_total: Option<bool>, ) -> Result<QueryChangesResponse, ClientError>
Fetch query-result changes for Mailbox since since_query_state
(RFC 8621 §2.4 — Mailbox/queryChanges).
filter and sort MUST match the filter / sort passed to the
original Mailbox/query call that returned since_query_state —
RFC 8620 §5.6 is explicit that the server uses them to compute
which entries entered or left the result set. Omitting them when
the original query had a non-trivial filter or sort gives the
wrong added/removed deltas (or cannotCalculateChanges).
up_to_id is the highest-index id the client has cached
(RFC 8620 §5.6); the server may use it to omit changes past that
point when both filter and sort are on immutable properties.
calculate_total requests the new total result count.
max_changes follows the same magic-value semantics as
Self::email_changes.
§Errors
ClientError::InvalidArgumentifsince_query_stateis the empty string (defence-in-depth empty-state guard; seeSelf::mailbox_changes).ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::mailbox_get. RFC 8620 §5.6 also definescannotCalculateChanges(returned when the server cannot honour the request given the supplied filter / sort); it surfaces asMethodError.
Source§impl SessionClient
impl SessionClient
Sourcepub async fn search_snippet_get(
&self,
filter: Value,
email_ids: Option<&[Id]>,
) -> Result<Value, ClientError>
pub async fn search_snippet_get( &self, filter: Value, email_ids: Option<&[Id]>, ) -> Result<Value, ClientError>
Fetch SearchSnippet objects (RFC 8621 §5.1 — SearchSnippet/get).
filter is the same filter object used in Email/query. email_ids
is the spec-defined list of Email ids to fetch snippets for; the
server returns one SearchSnippet
per email in the result set.
Callers wishing to fetch snippets for all emails in a set of threads
must resolve the thread membership first via Thread/get, then pass
the resulting email ids here — RFC 8621 §5.1 does not define a
threadIds argument on this method.
Returns the raw response value because the SearchSnippet/get response
shape differs from the standard /get shape (no state).
Callers should deserialize into Vec<jmap_mail_types::SearchSnippet> via
response["list"].as_array().
The account is the one bound to this SessionClient
— there is no caller-supplied override (closed bd:JMAP-tjvm.30 for
consistency with every other SessionClient method, which all derive
accountId from the session unconditionally).
§Errors
ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.- Any transport / protocol variant returned by
JmapClient::call:Http,Parse,AuthFailed,MethodError(wraps RFC 8620 §3.6.2 method-level errors such asaccountNotFound,invalidArguments,serverFail, and the /query-shape errorsunsupportedFilter/unsupportedSortper RFC 8621 §5.1),MethodNotFound,ResponseTooLarge, orUnexpectedResponse.
Source§impl SessionClient
impl SessionClient
Sourcepub async fn email_submission_get(
&self,
ids: Option<&[Id]>,
properties: Option<&[&str]>,
) -> Result<GetResponse<EmailSubmission>, ClientError>
pub async fn email_submission_get( &self, ids: Option<&[Id]>, properties: Option<&[&str]>, ) -> Result<GetResponse<EmailSubmission>, ClientError>
Fetch EmailSubmission objects by IDs (RFC 8621 §7.1 — EmailSubmission/get).
If ids is None, the server returns all submissions for the account,
SUBJECT TO the server’s maxObjectsInGet cap (RFC 8620 §5.1).
For production use, scope the result set via the corresponding
/query method first and pass explicit ids here to avoid
requestTooLarge errors when the account holds more objects
than the cap.
Pass properties: None to return all fields.
§Errors
ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail. (EmailSubmission/* usesurn:ietf:params:jmap:submissionin itsusingarray but is keyed on the mail primary account.)- Any transport / protocol variant returned by
JmapClient::call:Http,Parse,AuthFailed,MethodError(wraps RFC 8620 §3.6.2 method-level errors such asaccountNotFound,invalidArguments,serverFail),MethodNotFound,ResponseTooLarge, orUnexpectedResponse.
Sourcepub async fn email_submission_changes(
&self,
since_state: &State,
max_changes: Option<u64>,
) -> Result<ChangesResponse, ClientError>
pub async fn email_submission_changes( &self, since_state: &State, max_changes: Option<u64>, ) -> Result<ChangesResponse, ClientError>
Fetch changes to EmailSubmission objects since since_state
(RFC 8621 §7.2 — EmailSubmission/changes).
max_changes follows the same RFC 8620 §5.2 magic-value semantics
as SessionClient::email_changes:
None lets the server apply its default cap, Some(0) means
“no client limit”, Some(n>0) requests at most n entries.
§Errors
ClientError::InvalidArgumentifsince_stateis the empty string (defence-in-depth —Stateconstructed viaState::fromaccepts empty strings, but an emptysinceStateis never useful and would otherwise generate a wasted round-trip).ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::email_submission_get.
Sourcepub async fn email_submission_query(
&self,
filter: Option<Value>,
sort: Option<Value>,
position: Option<u64>,
limit: Option<u64>,
) -> Result<QueryResponse, ClientError>
pub async fn email_submission_query( &self, filter: Option<Value>, sort: Option<Value>, position: Option<u64>, limit: Option<u64>, ) -> Result<QueryResponse, ClientError>
Query EmailSubmission IDs with optional filter and sort (RFC 8621 §7.3 — EmailSubmission/query).
The sort property for this object type is "sentAt" (RFC 8621 §7.3, line 4513),
not "sendAt" (which is an object field). Callers constructing the sort
argument should use "sentAt" as the property name.
position and limit follow the same RFC 8620 §5.5 magic-value
semantics as
SessionClient::email_query:
position: Some(0) is the first item (zero-indexed); limit: Some(0) means “server’s default cap”, NOT “zero results”.
§Errors
ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::email_submission_get. RFC 8620 §5.5 defines additional /query method-level errors (anchorNotFound,unsupportedFilter,unsupportedSort,tooManyChanges) that surface asMethodError.
Sourcepub async fn email_submission_query_changes(
&self,
since_query_state: &State,
max_changes: Option<u64>,
filter: Option<Value>,
sort: Option<Value>,
up_to_id: Option<&Id>,
calculate_total: Option<bool>,
) -> Result<QueryChangesResponse, ClientError>
pub async fn email_submission_query_changes( &self, since_query_state: &State, max_changes: Option<u64>, filter: Option<Value>, sort: Option<Value>, up_to_id: Option<&Id>, calculate_total: Option<bool>, ) -> Result<QueryChangesResponse, ClientError>
Fetch query-result changes for EmailSubmission since since_query_state
(RFC 8621 §7.4 — EmailSubmission/queryChanges).
filter and sort MUST match the filter / sort passed to the
original EmailSubmission/query call that returned
since_query_state — RFC 8620 §5.6 is explicit that the server
uses them to compute which entries entered or left the result set.
Omitting them when the original query had a non-trivial filter or
sort gives the wrong added/removed deltas (or
cannotCalculateChanges).
up_to_id is the highest-index id the client has cached
(RFC 8620 §5.6); the server may use it to omit changes past that
point when both filter and sort are on immutable properties.
calculate_total requests the new total result count.
max_changes follows the same magic-value semantics as
SessionClient::email_changes.
§Errors
ClientError::InvalidArgumentifsince_query_stateis the empty string (defence-in-depth empty-state guard; seeSelf::email_submission_changes).ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::email_submission_get. RFC 8620 §5.6 also definescannotCalculateChanges(returned when the server cannot honour the request given the supplied filter / sort); it surfaces asMethodError.
Sourcepub async fn email_submission_set(
&self,
create: Option<Value>,
update: Option<HashMap<Id, PatchObject>>,
destroy: Option<Vec<Id>>,
if_in_state: Option<&State>,
params: Option<EmailSubmissionSetParams>,
) -> Result<SetResponse<EmailSubmission>, ClientError>
pub async fn email_submission_set( &self, create: Option<Value>, update: Option<HashMap<Id, PatchObject>>, destroy: Option<Vec<Id>>, if_in_state: Option<&State>, params: Option<EmailSubmissionSetParams>, ) -> Result<SetResponse<EmailSubmission>, ClientError>
Create, update, or destroy EmailSubmission objects (RFC 8621 §7.5 — EmailSubmission/set).
The optional params argument carries the two success-hook fields:
on_success_update_email— aPatchObjectmap (keyed by submission creation key) of patches to apply to the associated Email when the submission is created successfully (RFC 8621 §7.5).on_success_destroy_email— IDs (or#-reference creation keys) of Email objects to destroy when the submission is created successfully (RFC 8621 §7.5).
§Errors
ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.ClientError::InvalidArgumentifserde_json::to_valuefails onupdateor onparams.on_success_update_email(pathological conditions only; seeSelf::email_setfor the memory-cost discussion that applies identically here).- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::email_submission_get.
Source§impl SessionClient
impl SessionClient
Sourcepub async fn thread_get(
&self,
ids: Option<&[Id]>,
properties: Option<&[&str]>,
) -> Result<GetResponse<Thread>, ClientError>
pub async fn thread_get( &self, ids: Option<&[Id]>, properties: Option<&[&str]>, ) -> Result<GetResponse<Thread>, ClientError>
Fetch Thread objects by IDs (RFC 8621 §3.1 — Thread/get).
If ids is None, the server returns all Threads for the account,
SUBJECT TO the server’s maxObjectsInGet cap (RFC 8620 §5.1).
For production use, scope the result set via the corresponding
/query method first and pass explicit ids here to avoid
requestTooLarge errors when the account holds more objects
than the cap.
Pass properties: None to return all fields.
§Errors
ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.- Any transport / protocol variant returned by
JmapClient::call:Http,Parse,AuthFailed,MethodError(wraps RFC 8620 §3.6.2 method-level errors such asaccountNotFound,invalidArguments,serverFail),MethodNotFound,ResponseTooLarge, orUnexpectedResponse.
Sourcepub async fn thread_changes(
&self,
since_state: &State,
max_changes: Option<u64>,
) -> Result<ChangesResponse, ClientError>
pub async fn thread_changes( &self, since_state: &State, max_changes: Option<u64>, ) -> Result<ChangesResponse, ClientError>
Fetch changes to Thread objects since since_state (RFC 8621 §3.2 — Thread/changes).
If has_more_changes is true in the response, call again with new_state
as since_state until the flag is false.
max_changes follows the same RFC 8620 §5.2 magic-value semantics
as SessionClient::email_changes:
None lets the server apply its default cap, Some(0) means
“no client limit”, Some(n>0) requests at most n entries.
§Errors
ClientError::InvalidArgumentifsince_stateis the empty string (defence-in-depth —Stateconstructed viaState::fromaccepts empty strings, but an emptysinceStateis never useful and would otherwise generate a wasted round-trip).ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::thread_get.
Source§impl SessionClient
impl SessionClient
Sourcepub async fn vacation_response_get(
&self,
) -> Result<VacationResponse, ClientError>
pub async fn vacation_response_get( &self, ) -> Result<VacationResponse, ClientError>
Fetch the VacationResponse singleton for the account (RFC 8621 §8).
RFC 8621 §8 declares VacationResponse a per-account singleton
whose id is always "singleton"; one always exists per
account, defaulting to isEnabled: false. This method returns
the singleton value directly, unwrapping the standard /get
envelope (accountId, state, list, notFound). Callers
that need the envelope fields (e.g. the state token for a
subsequent VacationResponse/set ifInState guard) should call
Self::vacation_response_get_envelope instead.
§Errors
ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail. (VacationResponse/* usesurn:ietf:params:jmap:vacationresponsein itsusingarray but is keyed on the mail primary account.)ClientError::InvalidSessionif the server returns an emptylist— a protocol violation per RFC 8621 §8 (the singleton always exists).- Any transport / protocol variant returned by
JmapClient::call:Http,Parse,AuthFailed,MethodError(wraps RFC 8620 §3.6.2 method-level errors such asaccountNotFound,invalidArguments,serverFail),MethodNotFound,ResponseTooLarge, orUnexpectedResponse.
Sourcepub async fn vacation_response_get_envelope(
&self,
) -> Result<GetResponse<VacationResponse>, ClientError>
pub async fn vacation_response_get_envelope( &self, ) -> Result<GetResponse<VacationResponse>, ClientError>
Fetch the VacationResponse singleton including the standard
/get envelope (accountId, state, list, notFound).
Use this instead of Self::vacation_response_get when you
need access to the response state token (e.g. for a
subsequent VacationResponse/set ifInState guard) or to
distinguish the empty-list protocol-violation case from a
genuine missing-account error.
list always contains exactly one element on a spec-conformant
server; an empty list indicates a server bug. See
Self::vacation_response_get for the unwrap-and-validate
shape that callers typically want.
§Errors
Same set as Self::vacation_response_get, except this method
does NOT translate an empty list into
ClientError::InvalidSession.
Sourcepub async fn vacation_response_set(
&self,
update: Option<HashMap<Id, PatchObject>>,
) -> Result<SetResponse<VacationResponse>, ClientError>
pub async fn vacation_response_set( &self, update: Option<HashMap<Id, PatchObject>>, ) -> Result<SetResponse<VacationResponse>, ClientError>
Update the VacationResponse singleton (RFC 8621 §8).
update should be a JSON object of the form:
{ "singleton": { "isEnabled": true, "subject": "Out of office" } }create and destroy are not supported by VacationResponse/set.
update is Option<HashMap<Id, PatchObject>> (RFC 8620 §5.3). The
usual shape is {"singleton": <patch>}. Wire format is unchanged
from a plain JSON object because PatchObject is
#[serde(transparent)].
§Errors
ClientError::InvalidSessionif the bound session has no primary account forurn:ietf:params:jmap:mail.ClientError::InvalidArgumentifupdateisSomeandserde_json::to_valuefails on the patch map (pathological conditions only; seeSelf::email_setfor the memory-cost discussion that applies identically here).- Any transport / protocol variant returned by
JmapClient::call— see the matching error list onSelf::vacation_response_get.
Source§impl SessionClient
impl SessionClient
Sourcepub fn client(&self) -> &JmapClient
pub fn client(&self) -> &JmapClient
Borrow the underlying JmapClient.
Useful for ad-hoc operations outside the typed JMAP method surface —
for example, calling JmapClient::upload / JmapClient::download_blob
for attachment transfer, or constructing a JmapClient::event_source
subscription using the bound session’s event_source_url.
Returns a borrow so callers do not pay the small clone cost of
JmapClient::clone unless they need an owned handle.
Sourcepub fn session(&self) -> &Session
pub fn session(&self) -> &Session
Borrow the captured Session.
SessionClient captures the Session at construction time. After
re-fetching the session via JmapClient::fetch_session, callers
should construct a new SessionClient. This accessor lets a caller
compare the captured session’s state field against a freshly
fetched session to detect staleness, or inspect
accountCapabilities / primary_accounts for capability-specific
metadata not exposed via the typed JMAP method surface.
Sourcepub fn mail_account_id(&self) -> Result<&str, ClientError>
pub fn mail_account_id(&self) -> Result<&str, ClientError>
Return the primary mail account id for urn:ietf:params:jmap:mail,
or Err(InvalidSession) if the session has no primary account for
that capability.
The captured session contract is “this SessionClient is bound to
the JMAP Mail capability”; if the underlying primary-accounts map
no longer carries urn:ietf:params:jmap:mail, the session is
effectively useless for this crate’s methods. This accessor
surfaces that contract for callers who need the account id outside
the JMAP method calls (e.g. to thread it into a blob-upload URL
template).
Trait Implementations§
Source§impl Clone for SessionClient
impl Clone for SessionClient
Source§fn clone(&self) -> SessionClient
fn clone(&self) -> SessionClient
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more