jmap_filenode_types/capability.rs
1//! draft-ietf-jmap-filenode-13 §2.1 — account-level capability object.
2//!
3//! Provides [`FileNodeCapability`] and the capability URI constant
4//! [`JMAP_FILENODE_URI`].
5
6use serde::{Deserialize, Serialize};
7
8/// The JMAP capability URI for the FileNode extension.
9///
10/// Present as a key in both the session-level `capabilities` object (value:
11/// empty object) and in each account's `accountCapabilities` object (value:
12/// a [`FileNodeCapability`]).
13pub const JMAP_FILENODE_URI: &str = "urn:ietf:params:jmap:filenode";
14
15/// Account-level capability for the JMAP FileNode extension
16/// (draft-ietf-jmap-filenode-13 §2.1).
17///
18/// The value of the `urn:ietf:params:jmap:filenode` key in `accountCapabilities`.
19///
20/// ## Nullable fields
21///
22/// Fields typed `Option<T>` with no `skip_serializing_if` are **required-and-nullable**:
23/// they MUST appear in wire JSON even when the value is `null` (e.g. `"maxFileNodeDepth":null`
24/// means no limit). Fields with `skip_serializing_if = "Option::is_none"` are absent when
25/// `None`, but none exist on this struct — all optional fields here are nullable.
26///
27/// ## `maxSizeFileNodeName` constraint
28///
29/// Per §2.1 the server MUST set this to at least 100. This crate does not enforce
30/// the constraint at the type level (that would require a newtype); the server
31/// implementation is responsible for the invariant.
32#[non_exhaustive]
33#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
34#[serde(rename_all = "camelCase")]
35pub struct FileNodeCapability {
36 /// Maximum depth of the FileNode hierarchy (one more than the max ancestor count),
37 /// or `null` for no limit.
38 ///
39 /// Always serialized (as `null` when `None`).
40 pub max_file_node_depth: Option<u64>,
41
42 /// Maximum length, in UTF-8 octets, for a FileNode name. MUST be ≥ 100.
43 pub max_size_file_node_name: u64,
44
45 /// Characters forbidden in FileNode names, each character individually forbidden.
46 /// `null` means the server imposes no character restrictions beyond Net-Unicode.
47 ///
48 /// Always serialized (as `null` when `None`).
49 pub forbidden_name_chars: Option<String>,
50
51 /// Complete names the server will not accept (compared case-insensitively).
52 /// `null` means no specific names are forbidden.
53 ///
54 /// Always serialized (as `null` when `None`).
55 pub forbidden_node_names: Option<Vec<String>>,
56
57 /// All sort property values supported for the `"property"` field of a Comparator
58 /// object in `FileNode/query`.
59 pub file_node_query_sort_options: Vec<String>,
60
61 /// If `true`, the user may create a FileNode with a null `parentId` in this account.
62 pub may_create_top_level_file_node: bool,
63
64 /// Web URL for the folder with the `"trash"` role, or `null` if unavailable.
65 ///
66 /// Always serialized (as `null` when `None`).
67 pub web_trash_url: Option<String>,
68
69 /// If `true`, the server treats file names as case-insensitive for all name
70 /// collision checks (including the sibling uniqueness constraint and `onExists`
71 /// handling). The server preserves the original case as provided by the client.
72 pub case_insensitive_names: bool,
73
74 /// URI Template (level 1) for viewing a node on the web, with `{id}` variable.
75 /// `null` if no web URL is available.
76 ///
77 /// Always serialized (as `null` when `None`).
78 pub web_url_template: Option<String>,
79
80 /// URI Template (level 1) for direct HTTP writes to a file node, with `{id}`
81 /// variable. `null` if direct HTTP writes are not supported.
82 ///
83 /// Always serialized (as `null` when `None`).
84 pub web_write_url_template: Option<String>,
85}