jmap-metadata-client 0.4.2

JMAP Object Metadata extension client helpers (draft-ietf-jmap-metadata-04) — property constants, filter-condition builders, and /changes helpers for metadata-augmented requests
Documentation

jmap-metadata-client

What it is

Pure, stateless client-side helpers for the JMAP Object Metadata extension (draft-ietf-jmap-metadata-04). No SessionClient, no extension trait, no network I/O. Depends only on serde_json.

What it's for

draft-04 has no standalone Metadata object and no Metadata/* methods. Metadata is read and written through metadata / privateMetadata properties on each listed data type, using that type's own methods (§3). Use these helpers alongside the typed extension clients (jmap-mail-client, jmap-calendars-client, …):

Helper Use Draft §
METADATA_PROPERTY, PRIVATE_METADATA_PROPERTY names for a Foo/get properties list §2, §3.1
IGNORE_METADATA_ONLY_CHANGES Foo/changes request argument name §3.3
is_metadata_property, is_metadata_only_change classify a Foo/changes updatedProperties value §3.3
metadata_exists_condition, private_metadata_exists_condition metadataExists / privateMetadataExists filter conditions §3.6
metadata_text_contains_condition, private_metadata_text_contains_condition metadataTextContains / privateMetadataTextContains §3.6
metadata_text_equals_condition, private_metadata_text_equals_condition metadataTextEquals / privateMetadataTextEquals §3.6

JMAP_METADATA_URI, DataTypeMetadataInfo, MetadataTextMatch, and the namespace validators live in jmap-metadata-types; depend on it directly. This crate neither re-exports nor depends on it, so its public API (&str, bool, serde_json::Value) does not tie its major version to that crate's.

How to use

use jmap_metadata_client::{metadata_text_contains_condition, METADATA_PROPERTY};
use serde_json::json;

// Fetch an object's shared metadata alongside other properties (§3.1).
let properties = vec!["id", "name", METADATA_PROPERTY];
assert!(properties.contains(&"metadata"));

// Compose a metadata condition with the type's own conditions (§3.6).
// An extension client's `*_query` method takes it as
// `jmap_types::Filter::Condition(filter)`; for a typed tree, use
// `jmap_metadata_types::WithMetadata<C>` leaves instead.
let filter = json!({
    "operator": "AND",
    "conditions": [
        { "inMailbox": "MB-inbox" },
        metadata_text_contains_condition("acme.example.com/memo", "follow up"),
    ]
});
assert_eq!(
    filter["conditions"][1],
    json!({ "metadataTextContains": { "path": "acme.example.com/memo", "value": "follow up" } })
);

Gotchas

  • Pinned to draft-04. draft-02 was a complete rewrite of -01; later revisions (or a final RFC) may change the wire shape again.
  • Capability-dependent conditions. Any privateMetadata* condition is rejected with unsupportedFilter when the data type's supportsPrivate is false; servers MAY reject the four text-match conditions with unsupportedFilter and clients SHOULD be prepared to fall back to a client-side scan (§3.6). Check DataTypeMetadataInfo (jmap-metadata-types) in the account capability first.
  • Typed filters. The extension-types FilterCondition structs carry no metadata fields (bd JMAP-ua37.4). The extension clients' *_query / *_query_changes methods take a generic jmap_types::Filter<C>, so a typed tree uses jmap_metadata_types::WithMetadata<C> leaves and an untyped one is passed as Filter::Condition(value).

Migration from 0.3

The jmap-metadata-types re-exports (JMAP_METADATA_URI, DataTypeMetadataInfo, MetadataTextMatch, is_registered_namespace, is_valid_namespace, is_vendor_namespace) are removed. Import them from jmap_metadata_types instead.

Migration from 0.1 (draft-01)

The 0.1 crate exposed JmapMetadataExt, SessionClient, metadata_get, metadata_changes, metadata_set, metadata_query, metadata_query_changes, and their parameter structs. All are removed in 0.2.

Crate family

serde_json
    └── jmap-metadata-client  ← this crate (no jmap-* dependency)

References

  • draft-ietf-jmap-metadata-04 — JMAP Object Metadata (normative for property names, the /changes argument, and filter conditions).
  • RFC 8620 — JMAP Core (/get, /changes, /query, filter operators).