Commit Graph

55 Commits

Author SHA1 Message Date
90e746abdd Support vCard 4 TZ alternate value types 2026-03-28 20:28:22 -05:00
7e933dd30f Support vCard 4 LANG language-tag values 2026-03-28 20:28:00 -05:00
99a36f71d0 Add vCard 4 LANG and TZ value-type tests 2026-03-28 20:27:12 -05:00
8ea67163e7 Fix vCard 4 PID accessors 2026-03-28 20:23:46 -05:00
35e191d82b Round-trip vCard 4 URI media types 2026-03-28 20:23:31 -05:00
c2f194bdc2 Emit VALUE=text for vCard 4 date text values 2026-03-28 20:23:06 -05:00
4221b3af7c Preserve vCard 4 group prefixes in serializers 2026-03-28 20:22:46 -05:00
d3d5f46096 Fix vCard 4 text-list serialization 2026-03-28 20:22:23 -05:00
6b1dceb2cd Fix vCard 4 text-or-uri constructors 2026-03-28 20:22:00 -05:00
2ae016f426 Failing tests for vCard v4 fix sets. 2026-03-28 19:54:17 -05:00
e3f0fdc1ab Refactor vCard validation and canonicalize VERSION handling
Move whole-card cardinality checks into overloaded validate helpers in
the vCard 3 and vCard 4 modules, and have readVCard invoke those
validators after parsing instead of hard-coding property checks in the
shared parser.

For vCard 3, validate property cardinality directly from propertyCardMap
and add regression coverage for duplicate single-cardinality properties.
For vCard 4, validate from propertyCardMap as well, while preserving
ALTID semantics for single-cardinality properties so alternate
representations remain valid and duplicate ungrouped properties are
rejected.

Rework VERSION handling to treat it as parser metadata rather than
stored card content. Parsing still requires exactly one canonical
VERSION line and rejects missing or duplicate occurrences, but parsed
cards no longer retain VC3_Version or VC4_Version objects in content.
Accessors and serializers continue to expose and emit the canonical
version for the concrete card type, which keeps parsed and
programmatically constructed cards on the same model.

Update the vCard 3 and vCard 4 test suites to cover the new validation
path, confirm VERSION is not persisted in content, and adjust fixture
expectations to match the canonical VERSION model.

AI-Assisted: yes
AI-Tool: OpenAI Codex / gpt-5.4 xhigh
2026-03-28 19:41:09 -05:00
cfac536d60 Fix vCard 3 PROFILE and AGENT handling
Parse PROFILE as the concrete VC3_Profile type instead of a bare
VC3_Property, and validate PROFILE parameters under the correct
content-type name.

Preserve AGENT values in newVC3_Agent so both parsed and constructed
AGENT properties serialize with their actual URI or inline content.

Expand regression coverage to verify PROFILE is exposed and serialized
as the standard property, parsed AGENT URI values round-trip correctly,
and constructed AGENT values retain their content.

AI-Assisted: yes
AI-Tool: OpenAI Codex / gpt-5.4 xhigh
2026-03-28 13:33:20 -05:00
8f2a05cde6 Fix vCard 3 REV and KEY value handling
Bring the remaining vCard 3 REV and KEY behavior into line with RFC
2426.

For REV, serialize VALUE=date using the date form instead of incorrectly
emitting VALUE=date-time with a timestamp payload.

For KEY, stop defaulting constructed values to VALUE=uri. The vCard 3
specification defines KEY as binary by default and allows it to be reset
to text, but not to uri. Tighten both construction and parsing
accordingly: reject VALUE=uri for KEY, enforce the relationship between
VALUE=binary and ENCODING=b, and reject VALUE=text when ENCODING=b is
present.

Update the regression coverage to reflect the spec boundary: PHOTO,
LOGO, and SOUND may round-trip as uris; KEY may contain text that looks
like a URI; KEY does not allow VALUE=uri; and vCard 3 KEY parameters
still require name=value syntax.

AI-Assisted: yes
AI-Tool: OpenAI Codex / gpt-5.4 xhigh
2026-03-28 10:46:41 -05:00
6e6e06bdc4 Fix quoted MIME-DIR parameter parsing
Correct the vCard 3 parameter parser so quoted parameter values are
consumed according to the MIME-DIR grammar instead of failing
immediately on the opening double quote.

The fix explicitly advances past the opening quote, reads the quoted
qsafe-char sequence, and strips the surrounding quotes from the returned
parameter value. Unquoted parameter handling is unchanged.

Add private parser coverage for quoted parameter values and quoted
values containing commas, plus a public regression test showing that
quoted LANGUAGE and TYPE parameters are accepted by the vCard 3 parser.

AI-Assisted: yes
AI-Tool: OpenAI Codex / gpt-5.4 xhigh
2026-03-28 10:32:58 -05:00
201556ecbe Fix vCard 3 text escaping and decoding
Implement RFC 2426 text escaping consistently across vCard 3
serialization and parsing.

On serialization, escape backslashes, newlines, semicolons, and commas
for simple text properties, structured text components, and list-valued
text properties so generated FN, N, ADR, ORG, CATEGORIES, and related
properties are spec-compliant on the wire.

On parsing, decode escaped text for the properties that were previously
read as raw values: FN, NICKNAME, LABEL, MAILER, TITLE, ROLE, PRODID,
and SORT-STRING. This preserves existing structured-text parsing for N,
ADR, NOTE, ORG, and CATEGORIES while fixing the direct raw-value
mismatch identified in the review.

Add regression coverage for both directions: parsing escaped text values
and serializing escaped simple, structured, and list text values.

AI-Assisted: yes
AI-Tool: OpenAI Codex / gpt-5.4 xhigh
2026-03-28 10:27:37 -05:00
35377f5a25 Fix vCard 3 inline binary round-tripping
Decode ENCODING=b payloads for PHOTO, LOGO, SOUND, and KEY when parsing
so serializing a parsed card does not base64-encode already encoded wire
data a second time. Add regression coverage for both inline binary and
VALUE=uri round-trips.

AI-Assisted: yes
AI-Tool: OpenAI Codex /gpt-5.4 xhigh
2026-03-28 10:13:52 -05:00
466e47fd36 Fix vCard folding and group parsing rules
Accept horizontal-tab continuations when unfolding content lines and
allow hyphens in group names, matching the MIME-DIR and vCard grammar.
Also add focused private tests covering both cases.

AI-Assisted: yes
AI-Tool: OpenAI Codex / gpt-5.4 xhigh
2026-03-28 10:04:53 -05:00
3d2d40667d Add a unified test runner for better test output. 2026-03-28 10:03:43 -05:00
c9de20f3a7 WIP: Test cases covering findings surfaced by ChatGPT. 2026-03-28 09:58:12 -05:00
ab2579bdb5 Modifications to compile under Nim 2.x 2026-03-28 09:55:17 -05:00
ce70e5ddd4 Bump version in prep for release. 2023-05-03 07:11:32 -05:00
935f1bae2f WIP documentation
- The documentation is cluttered enough as it is with the large number
  of procedures supporting vCard 3 and 4. Split common out into the
  publicly exposed bits and the private internals. This makes it obvious
  which common functionality a client can expect to have exposed on the
  main vcard module.

- Add documentation (WIP) on the vcard3 module.
2023-05-03 02:16:18 -05:00
0ec1856d1b lexer: Add comments documenting the implementation and expected behavior. 2023-05-03 01:05:02 -05:00
ddddcf0af9 vcard4: Use VC_Param instead of VCParam for consistency. 2023-05-03 00:29:55 -05:00
5565087359 common: Reformat for clarity, documentation.
- Consolidate `vcard/private/util` into `vcard/private/common`.
2023-05-03 00:28:26 -05:00
98c300fee2 vcard4: Complete implementation.
- Parsers and serializers are now present for all property types.
- Tests exist to cover parsing for most value types. Many property types
  share the same parsing logic based on their value type. We have
  created unit tests to cover each value type, not neccesarily all
  properties individually.
2023-05-02 22:37:23 -05:00
daa58518e3 vcard3: Unify with VCard4 implementation.
- Unify the naming pattern of types and enums. Specifically:
  - use `VC_Param` instead of `VCParam`. The goal here is to make the
    important information (Param, Source, PropertyName, etc.) easy to
    see at a glance while preserving a prefix that allows multiple
    implementation to coexist (VC3_Source vs. VC4_Source) and also be
    easily distinguishable at a glance.
  - use `pnName` instead of `cnName`. The VCard standard refers to each
    line of data as a "content line," so the original name of each was
    "Content." However, the spec more commonly refers to each piece of
    data as a "property." There is a 1-to-1 mapping of content lines to
    property instances, but property is a more accurate name.

- Introduce the idea of property cardinality to the VCard3
  implementation. The spec does not tightly define property cardinality,
  but implies it with statements like "if the NAME type is present, then
  *its* value is *the* displayable, presentation text associated..."
  (emphasis added). Similar language implies some properties must be
  present exactly once (FN, N, VERSION) or at most once (NAME, PROFILE,
  SOURCE, BDAY, CATEGORIES, PRODID, REV, SORT-STRING, UID). Any other
  properties are assumed to be allowed any number of times (including
  0).

  In the case of a VCard that contains multiple instances of properties
  expected to be singular, the parser will still parse and store these
  properties. They can be accessed via the `vcard#allPropsOfType`
  function. For example:

      # vc3 is a VCard3
      allPropsOfType[VC3_N](vc3)

  If we see over the course of time that other implementations regularly
  use multiple instances of properties we have expected to be singular,
  we are open to changing the contract to treat them so (though this
  may be a breaking change).

- Refactor the VCard3 implementation to use generated property
  accessors, following a similar pattern to the new VCard4
  implementation.

- Remove the accessor definitions that allow access via the content seq
  directly (`vc3.content.name` for example). There really isn't a reason
  for this use-case and the library is simpler without exposing this.
2023-05-02 22:36:27 -05:00
8e25c3d100 lexer, common: More descriptive error messages.
The lexer now tracks the data that has been read since the start of the
current line. While this may have use in parsers, the immediate use is
by the common error reporting procedure.

The `common#error` procedure already reports the column and line number
where an error occurs. The `common#expect` function is broadly used by
parsers and generates the majority of parser errors. It now uses the
lexer's record of the current line to format its error message with a
direct pointer to the location of the unmet expectation.
2023-05-02 22:11:00 -05:00
71107dda1c lexer: Add readLen and readRunesLen.
Convenience methods for cases where a parser knows it wants to read
multiple bytes or runes from the input stream.
2023-05-02 22:05:00 -05:00
cf4c14f9f8 Makefiles: update tests to ignore the BareExcept warning.
The `unittest` library still contains a number of bare exceptions, which
now result in warnings from the compliler. Patching the standard library
to remove these warnings is outside the scope of this project, so we're
going to ignore these warnings.
2023-05-02 21:32:30 -05:00
31f47f60c2 Makefile: Updates to testing targets. 2023-04-23 22:55:41 -05:00
f59403ad72 WIP - initial VCard4 implementation. 2023-04-23 21:56:15 -05:00
7d642adf2d RFC 6868: erratta for VCard4 parameter escaping mechanism. 2023-04-23 21:56:15 -05:00
3f1efe9e85 Makefile. 2023-04-23 21:56:15 -05:00
6bbcd9b6a3 lexer: Support multiple nested bookmarks. 2023-04-23 21:56:10 -05:00
8e58189a8b Re-organizing code in preparation for v4.0 implementation. 2023-04-23 21:56:04 -05:00
9d030132de Better ignore pattern for test artifacts. 2023-04-23 21:55:53 -05:00
68554920e5 Fix bug in parsing TEL content. Rework unit tests.
- newVC3_Tel was not assigning the value provided to the constructed
  object.
- Private unit tests were run every time the code was compiled due to
  how the unittest library works. These now only run as part of the unit
  tests with `nimble test`.
0.1.3
2023-04-16 03:34:14 -05:00
7b71cb2dfe Extract example from the README to a runnable location. 2023-04-16 03:31:37 -05:00
47c62cce6d Restructure to follow standard nimble package format. 0.1.2 2023-04-15 07:40:58 -05:00
a1dac6eaaf Bump version. 0.1.1 2023-04-15 07:09:55 -05:00
2c625349bf README: add simple usage. 2023-04-15 07:09:03 -05:00
0f353e97ca Add test case for email preference. 2023-04-15 07:08:30 -05:00
c4717b4b00 Date types default to date-time as specified.
- `parseDateOrDateTime attempts to parse times starting from the most
  specific (date and time) to least specific.
- `set` and `add` functions allow adding multiple content items at once
  using varargs.
2023-04-15 07:03:24 -05:00
419d794c68 Added RFC 6352 (CardDav). 2023-04-15 06:58:57 -05:00
a0cd676521 Fix defect found testing EMAIL content types. 2023-04-10 16:10:49 -05:00
2a48974f3a Add basic description in the README. 2023-04-05 09:42:16 -05:00
82dffc1154 Initial VCard 3.0 implementation completed. 0.1.0 2023-04-04 14:31:44 -05:00
c322616747 WIP lexer unit tests. 2023-04-01 17:36:01 -05:00
2bc5d5c74f WIP vcard 3.0 lexer and parser. 2023-04-01 16:29:30 -05:00