use std::{ borrow::Cow, collections::{BTreeSet, HashMap}, }; use serde::{Deserialize, Serialize}; use serde_json::Value; use serde_with::{serde_as, BorrowCow}; use crate::common::{Id, SessionState, UnsignedInt}; /// Implementors must take care to avoid inappropriate caching of the /// Session object at the HTTP layer. Since the client should only /// refetch when it detects there is a change (via the sessionState /// property of an API response), it is RECOMMENDED to disable HTTP /// caching altogether, for example, by setting "Cache-Control: no-cache, /// no-store, must-revalidate" on the response. /// /// Exposed from https://${hostname}[:${port}]/.well-known/jmap #[serde_as] #[derive(Deserialize, Serialize, Clone, Debug)] #[serde(rename_all = "camelCase")] pub struct Session<'a> { /// An object specifying the capabilities of this server. Each key is /// a URI for a capability supported by the server. The value for /// each of these keys is an object with further information about the /// server's capabilities in relation to that capability. /// /// The capabilities object MUST include a property called /// "urn:ietf:params:jmap:core". #[serde(borrow)] pub capabilities: HashMap, Value>, /// A map of an account id to an Account object for each account (see /// Section 1.6.2) the user has access to. #[serde(borrow)] pub accounts: HashMap, Account<'a>>, /// A map of capability URIs (as found in accountCapabilities) to the /// account id that is considered to be the user's main or default /// account for data pertaining to that capability. If no account /// being returned belongs to the user, or in any other way there is /// no appropriate way to determine a default account, there MAY be no /// entry for a particular URI, even though that capability is /// supported by the server (and in the capabilities object). /// "urn:ietf:params:jmap:core" SHOULD NOT be present. #[serde_as(as = "HashMap")] pub primary_accounts: HashMap, Id<'a>>, /// The username associated with the given credentials, or the empty /// string if none. #[serde(borrow)] pub username: Cow<'a, str>, /// The URL to use for JMAP API requests. #[serde(borrow)] pub api_url: Cow<'a, str>, /// The URL endpoint to use when downloading files, in URI Template /// (level 1) format [RFC6570]. The URL MUST contain variables called /// "accountId", "blobId", "type", and "name". The use of these /// variables is described in Section 6.2. Due to potential encoding /// issues with slashes in content types, it is RECOMMENDED to put the /// "type" variable in the query section of the URL. #[serde(borrow)] pub download_url: Cow<'a, str>, /// The URL endpoint to use when uploading files, in URI Template /// (level 1) format [RFC6570]. The URL MUST contain a variable /// called "accountId". The use of this variable is described in /// Section 6.1. #[serde(borrow)] pub upload_url: Cow<'a, str>, /// The URL to connect to for push events, as described in /// Section 7.3, in URI Template (level 1) format [RFC6570]. The URL /// MUST contain variables called "types", "closeafter", and "ping". /// The use of these variables is described in Section 7.3. #[serde(borrow)] pub event_source_url: Cow<'a, str>, /// A (preferably short) string representing the state of this object /// on the server. If the value of any other property on the Session /// object changes, this string will change. The current value is /// also returned on the API Response object (see Section 3.4), /// allowing clients to quickly determine if the session information /// has changed (e.g., an account has been added or removed), so they /// need to refetch the object. #[serde(borrow)] pub state: SessionState<'a>, } #[serde_as] #[derive(Serialize, Deserialize, Clone, Debug)] #[serde(rename_all = "camelCase")] pub struct CoreCapability<'a> { /// The maximum file size, in octets, that the server will accept /// for a single file upload (for any purpose). Suggested minimum: /// 50,000,000. pub max_size_upload: UnsignedInt, /// The maximum number of concurrent requests the server will /// accept to the upload endpoint. Suggested minimum: 4. pub max_concurrent_upload: UnsignedInt, /// The maximum size, in octets, that the server will accept for a /// single request to the API endpoint. Suggested minimum: /// 10,000,000. pub max_size_request: UnsignedInt, /// The maximum number of concurrent requests the server will /// accept to the API endpoint. Suggested minimum: 4. pub max_concurrent_requests: UnsignedInt, /// The maximum number of method calls the server will accept in a /// single request to the API endpoint. Suggested minimum: 16. pub max_calls_in_request: UnsignedInt, /// The maximum number of objects that the client may request in a /// single /get type method call. Suggested minimum: 500. pub max_objects_in_get: UnsignedInt, /// The maximum number of objects the client may send to create, /// update, or destroy in a single /set type method call. This is /// the combined total, e.g., if the maximum is 10, you could not /// create 7 objects and destroy 6, as this would be 13 actions, /// which exceeds the limit. Suggested minimum: 500. pub max_objects_in_set: UnsignedInt, /// A list of identifiers for algorithms registered in the /// collation registry, as defined in [RFC4790], that the server /// supports for sorting when querying records. #[serde_as(as = "BTreeSet")] pub collation_algorithms: BTreeSet>, } #[serde_as] #[derive(Serialize, Deserialize, Clone, Debug)] #[serde(rename_all = "camelCase")] pub struct Account<'a> { /// A user-friendly string to show when presenting content from /// this account, e.g., the email address representing the owner of /// the account. #[serde(borrow)] pub name: Cow<'a, str>, /// This is true if the account belongs to the authenticated user /// rather than a group account or a personal account of another /// user that has been shared with them. pub is_personal: bool, /// This is true if the entire account is read-only. pub is_read_only: bool, /// The set of capability URIs for the methods supported in this /// account. Each key is a URI for a capability that has methods /// you can use with this account. The value for each of these /// keys is an object with further information about the account's /// permissions and restrictions with respect to this capability, /// as defined in the capability's specification. pub account_capabilities: AccountCapabilities, } #[derive(Serialize, Deserialize, Clone, Debug)] #[serde(rename_all = "camelCase")] pub struct AccountCapabilities {}