Skip to main content

JmapClient

Struct JmapClient 

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

Auth-agnostic JMAP base HTTP client.

Construct with JmapClient::new or JmapClient::new_plain. Extension-specific clients (jmap-chat-client, jmap-mail-client) depend on this crate and add their method implementations via impl JmapClient.

Implementations§

Source§

impl JmapClient

Source

pub async fn upload_blob( &self, upload_url_template: &str, account_id: &str, data: Bytes, content_type: &str, ) -> Result<BlobUploadResponse, ClientError>

Upload raw bytes to the JMAP blob store (RFC 8620 §6.1).

upload_url_template is from Session.upload_url; {accountId} is substituted before the request. content_type is sent as the Content-Type header. If the server returns a sha256 field (JMAP-CID capability), it is verified against the locally-computed digest and ClientError::BlobIntegrityMismatch is returned on mismatch.

Source

pub async fn download_blob( &self, params: DownloadBlobParams<'_>, ) -> Result<Bytes, ClientError>

Download a blob by ID (RFC 8620 §6.2).

Template variables {accountId}, {blobId}, {name}, and {type} are substituted from the corresponding fields of params before the GET request. {type} expands to an empty string when params.accept_type is None; templates that include ?accept={type} produce ?accept=. If the server does not tolerate an empty ?accept= parameter, omit {type} from the download_url template in the Session document.

If params.expected_sha256 is Some, the downloaded bytes are verified against the hex digest and ClientError::BlobIntegrityMismatch is returned on mismatch.

Source§

impl JmapClient

Source

pub fn new( transport: impl TransportConfig, auth: impl AuthProvider + 'static, base_url: &str, config: ClientConfig, ) -> Result<Self, ClientError>

Create a new client.

transport configures the underlying HTTP client (TLS trust roots, client certificates, timeouts). auth injects per-request credentials (Bearer token, Basic credentials, or none). The two are independent so any transport can be paired with any credential scheme — for example, CustomCaTransport with BearerAuth. base_url must be the server origin (scheme, host, optional port) with no path, query, or fragment — e.g. "https://100.64.1.1:8008". Trailing slashes are normalized away by the URL parser and are therefore accepted.

Source

pub fn new_plain( auth: impl AuthProvider + 'static, base_url: &str, config: ClientConfig, ) -> Result<Self, ClientError>

Convenience constructor for servers with publicly-trusted TLS.

Equivalent to JmapClient::new(DefaultTransport, auth, base_url, config). Use JmapClient::new when you need a custom transport (e.g. CustomCaTransport for a private-CA server).

Source

pub async fn fetch_session(&self) -> Result<Session, ClientError>

Fetch the JMAP Session object from {base_url}/.well-known/jmap (RFC 8620 §2).

The response body is capped at 1 MiB. Returns ClientError::ResponseTooLarge if the server sends more. Session URL fields (apiUrl, uploadUrl, downloadUrl, eventSourceUrl) are validated to have http/https scheme; a non-http scheme returns ClientError::InvalidSession.

Returns ClientError::AuthFailed on HTTP 401 or 403.

Source

pub async fn call( &self, api_url: &str, req: &JmapRequest, ) -> Result<JmapResponse, ClientError>

POST a jmap_types::JmapRequest to api_url and return the parsed jmap_types::JmapResponse (RFC 8620 §3.3).

api_url is taken as an explicit parameter (not from self) because the caller holds a Session and selects the correct URL from it.

The response body is capped at 8 MiB. Returns ClientError::ResponseTooLarge if the server sends more.

Returns ClientError::AuthFailed on HTTP 401 or 403.

Source

pub async fn subscribe_events( &self, event_source_url: &str, last_event_id: Option<&str>, ) -> Result<BoxStream<'static, Result<SseFrame, ClientError>>, ClientError>

Open an SSE connection to event_source_url and return an async stream of parsed SseFrames (RFC 8620 §7.3).

§URI template expansion

Session.event_source_url is a URI template (RFC 6570 Level-1) with variables types, closeafter, and ping. You must expand it before passing it to this function, or the server will receive the literal text {types} in the URL and return an error. Use expand_url_template:

let url = jmap_base_client::expand_url_template(
    &session.event_source_url,
    &[("types", "*"), ("closeafter", "no"), ("ping", "0")],
)?;
let stream = client.subscribe_events(&url, None).await?;

If last_event_id is Some, sends a Last-Event-ID header so the server can resume from where the previous stream left off.

Buffer growth is capped at ClientConfig::max_sse_frame bytes per frame (default: 1 MiB). If a single SSE frame exceeds this limit the stream yields ClientError::SseFrameTooLarge and terminates.

No timeout is applied to this call or to the resulting stream. The connect timeout (10 s, TCP only) is the only deadline enforced. If the server stalls before sending HTTP response headers, or later goes silent on the open connection, this call or the stream will hang indefinitely. Wrap the entire call and/or stream iteration in tokio::time::timeout if you need to bound either phase.

Returns ClientError::AuthFailed on HTTP 401 or 403 before the stream starts.

Trait Implementations§

Source§

impl Clone for JmapClient

Source§

fn clone(&self) -> JmapClient

Returns a duplicate of the value. Read more
1.0.0 · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Debug for JmapClient

Source§

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

Formats the value using the given formatter. 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: 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: 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 = 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