]> git.notmuchmail.org Git - notmuch/blobdiff - devel/schemata
devel/schemata: describe version 4
[notmuch] / devel / schemata
index e44da717b36c1dd18eb8e0f73112be9136032ecf..42b1bcf3a23900f1ca95509b09f2b3a7bd918fac 100644 (file)
@@ -1,5 +1,5 @@
 This file describes the schemata used for notmuch's structured output
-format (currently JSON).
+format (currently JSON and S-Expressions).
 
 []'s indicate lists.  List items can be marked with a '?', meaning
 they are optional; or a '*', meaning there can be zero or more of that
@@ -8,6 +8,32 @@ values.  An object field marked '?' is optional.  |'s indicate
 alternates (e.g., int|string means something can be an int or a
 string).
 
+For S-Expression output, lists are printed delimited by () instead of
+[]. Objects are printed as p-lists, i.e. lists where the keys and values
+are interleaved. Keys are printed as keywords (symbols preceded by a
+colon), e.g. (:id "123" :time 54321 :from "foobar"). Null is printed as
+nil, true as t and false as nil.
+
+This is version 4 of the structured output format.
+
+Version history
+---------------
+
+v1
+- First versioned schema release.
+- Added part.content-length and part.content-transfer-encoding fields.
+
+v2
+- Added the thread_summary.query field.
+
+v3
+- Replaced message.filename string with a list of filenames.
+- Added part.content-disposition field.
+
+v4
+- replace signature error integer bitmask with a set of flags for
+  individual errors.
+
 Common non-terminals
 --------------------
 
@@ -36,12 +62,12 @@ thread_node = [
     [thread_node*]            # children of message
 ]
 
-# A message (format_part_json)
+# A message (format_part_sprinter)
 message = {
-    # (format_message_json)
+    # (format_message_sprinter)
     id:             messageid,
     match:          bool,
-    filename:      string,
+    filename:      [string*],
     timestamp:      unix_time, # date header as unix time
     date_relative:  string,   # user-friendly timestamp
     tags:           [string*],
@@ -50,7 +76,7 @@ message = {
     body?:          [part]    # omitted if --body=false
 }
 
-# A MIME part (format_part_json)
+# A MIME part (format_part_sprinter)
 part = {
     id:             int|string, # part id (currently DFS part number)
 
@@ -58,6 +84,7 @@ part = {
     sigstatus?:     sigstatus,
 
     content-type:   string,
+    content-disposition?:       string,
     content-id?:    string,
     # if content-type starts with "multipart/":
     content:        [part*],
@@ -69,10 +96,17 @@ part = {
     # A leaf part's body content is optional, but may be included if
     # it can be correctly encoded as a string.  Consumers should use
     # this in preference to fetching the part content separately.
-    content?:       string
+    content?:       string,
+    # If a leaf part's body content is not included, the length of
+    # the encoded content (in bytes) may be given instead.
+    content-length?: int,
+    # If a leaf part's body content is not included, its transfer encoding
+    # may be given.  Using this and the encoded content length, it is
+    # possible for the consumer to estimate the decoded content length.
+    content-transfer-encoding?: string
 }
 
-# The headers of a message or part (format_headers_json with reply = FALSE)
+# The headers of a message or part (format_headers_sprinter with reply = FALSE)
 headers = {
     Subject:        string,
     From:           string,
@@ -83,15 +117,15 @@ headers = {
     Date:           string
 }
 
-# Encryption status (format_part_json)
+# Encryption status (format_part_sprinter)
 encstatus = [{status: "good"|"bad"}]
 
-# Signature status (format_part_sigstatus_json)
+# Signature status (format_part_sigstatus_sprinter)
 sigstatus = [signature*]
 
 signature = {
     # (signature_status_to_string)
-    status:         "none"|"good"|"bad"|"error"|"unknown",
+    status:         "good"|"bad"|"error"|"unknown",
     # if status is "good":
     fingerprint?:   string,
     created?:       unix_time,
@@ -99,29 +133,41 @@ signature = {
     userid?:        string
     # if status is not "good":
     keyid?:         string
-    # if the signature has errors:
-    errors?:        int
+    errors?:       sig_errors
+}
+
+sig_errors = {
+    key-revoked?: bool,
+    key-expired?: bool,
+    sig-expired?: bool,
+    key-missing?: bool,
+    alg-unsupported?: bool,
+    crl-missing?: bool,
+    crl-too-old?: bool,
+    bad-policy?: bool,
+    sys-error?: bool,
+    tofu-conflict?: bool
 }
 
 notmuch search schema
 ---------------------
 
 # --output=summary
-summary = [thread*]
+search_summary = [thread_summary*]
 
 # --output=threads
-threads = [threadid*]
+search_threads = [threadid*]
 
 # --output=messages
-messages = [messageid*]
+search_messages = [messageid*]
 
 # --output=files
-files = [string*]
+search_files = [string*]
 
 # --output=tags
-tags = [string*]
+search_tags = [string*]
 
-thread = {
+thread_summary = {
     thread:         threadid,
     timestamp:      unix_time,
     date_relative:  string,   # user-friendly timestamp
@@ -130,7 +176,15 @@ thread = {
     authors:        string,   # comma-separated names with | between
                               # matched and unmatched
     subject:        string,
-    tags:           [string*]
+    tags:           [string*],
+
+    # Two stable query strings identifying exactly the matched and
+    # unmatched messages currently in this thread.  The messages
+    # matched by these queries will not change even if more messages
+    # arrive in the thread.  If there are no matched or unmatched
+    # messages, the corresponding query will be null (there is no
+    # query that matches nothing).  (Added in schema version 2.)
+    query:          [string|null, string|null],
 }
 
 notmuch reply schema
@@ -140,11 +194,11 @@ reply = {
     # The headers of the constructed reply
     reply-headers: reply_headers,
 
-    # As in the show format (format_part_json)
+    # As in the show format (format_part_sprinter)
     original: message
 }
 
-# Reply headers (format_headers_json with reply = TRUE)
+# Reply headers (format_headers_sprinter with reply = TRUE)
 reply_headers = {
     Subject:        string,
     From:           string,