#[non_exhaustive]pub struct Link {
pub at_type: String,
pub href: Option<String>,
pub content_type: Option<String>,
pub size: Option<u64>,
pub rel: Option<String>,
pub display: Option<String>,
pub cid: Option<String>,
pub title: Option<String>,
pub blob_id: Option<Id>,
pub extra: Map<String, Value>,
}Expand description
An attachment, image, or URL associated with an event (RFC 8984 §1.4.11).
§Source invariant: at least one of href or blob_id MUST be set
RFC 8984 §1.4.11 marks href as "String" (mandatory). The JMAP
Calendars draft (draft-ietf-jmap-calendars-26 §5.3) relaxes that
mandate: “Instead of mandating an ‘href’ property, clients may set a
‘blobId’ property instead to reference a blob of binary data in the
account”. The combined contract is therefore exactly one of
href or blob_id MUST be present, and both MAY be set
simultaneously (a server-stored blob with a public-fetch URL).
This invariant is not encoded in the Rust type — both fields are
Option so that partial deserialization (e.g. of an in-flight update
where only one half has been populated) succeeds. Encoding the
invariant via enum LinkSource { Href, BlobId, Both } would be a
breaking API change and is deliberately deferred until consumer
evidence warrants it.
Consumers that need to validate the invariant on inbound data check it themselves; validation lives outside this crate (bd:JMAP-ops7.38).
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.at_type: StringObject type discriminator; always "Link" on the wire.
Deserialize is liberal: if @type is absent (spec-violating
vendor input), this field defaults to "Link" rather than
failing the whole parent object’s deserialize. Serialize always
emits the field. See bd:JMAP-ky8g.10.
href: Option<String>URI from which the linked resource may be fetched (RFC 8984
§1.4.11 — "String" (mandatory)).
The pure RFC 8984 mandate is relaxed by the JMAP Calendars draft
(draft-ietf-jmap-calendars-26 §5.3) when blob_id is set: the
client may omit href and reference the resource by JMAP blob
id instead. At least one of href or blob_id MUST be
present on a well-formed Link; see the struct-level docs.
content_type: Option<String>Content type (MIME type) of the linked resource.
size: Option<u64>Size of the linked resource in bytes.
rel: Option<String>Relationship of this link to the event (e.g. "enclosure", "describedby").
display: Option<String>Display/file name for the link.
cid: Option<String>Content-id value for inline images embedded in a text/html description
via cid: URLs (RFC 8984 §1.4.11).
Only meaningful when CalendarEvent.descriptionContentType is text/html
and the HTML body references this link as <img src="cid:…">.
title: Option<String>Human-readable, plain-text description of the linked resource (RFC 8984 §1.4.11).
Distinct from display (which is a file name); title is a longer
description suitable for accessibility text or tooltips.
blob_id: Option<Id>JMAP blob id (draft-ietf-jmap-calendars-26 §5.3 / §10.9.14).
When present, href may be absent — the JMAP Calendars draft
§5.3 explicitly permits substituting a blob_id for the
otherwise-mandatory href. At least one of href or
blob_id MUST be present on a well-formed Link; see the
struct-level docs.
Per draft §5.3: the server MUST translate this to an embedded
data: URL when sending to systems that cannot access blobs.
extra: Map<String, Value>Catch-all for vendor / site / private extension fields not covered by the typed fields above. Preserves unknown fields across deserialize/serialize round-trip per workspace extras-preservation policy (see workspace AGENTS.md).