vCard 4.0 parser and serialiser. vCard 3.0 is explicitly rejected.
Only the properties needed for CardDAV are handled: FN, N, EMAIL, TEL,
ADR, ORG, NOTE, UID, REV, plus a catch-all for unknown properties.
Unknown properties are round-tripped verbatim as {"RAW", line} entries.
Returned map keys are downcased atoms where known, :raw list otherwise.
Summary
Functions
Compute an ETag for a vCard body (same algorithm as ICal.etag/1).
Extract the UID from a vCard string. Returns nil if not present or invalid.
Parse a vCard 4.0 string. Returns {:ok, map} or
{:error, reason} where reason is a string.
Serialise a map (as returned by parse/1) back to a vCard 4.0 string.
Validate a vCard 4.0 PUT body. Returns :ok or
{:error, reason} with one of
Functions
Compute an ETag for a vCard body (same algorithm as ICal.etag/1).
Extract the UID from a vCard string. Returns nil if not present or invalid.
Parse a vCard 4.0 string. Returns {:ok, map} or
{:error, reason} where reason is a string.
The returned map has:
:fn— full name string:n— structured name string:email— list of email strings:tel— list of tel strings:adr— list of address strings:org— org string:note— note string:uid— uid string:rev— revision string:raw— list of verbatim lines for unknown properties
Serialise a map (as returned by parse/1) back to a vCard 4.0 string.
@spec validate(String.t()) :: :ok | {:error, :not_vcard | :wrong_version | :missing_fn}
Validate a vCard 4.0 PUT body. Returns :ok or
{:error, reason} with one of:
:not_vcard— missing BEGIN:VCARD / END:VCARD:wrong_version— VERSION is not 4.0:missing_fn— FN property absent