Re: [PATCH v4 1/3] Add support for structured output formatters.

Subject: Re: [PATCH v4 1/3] Add support for structured output formatters.

Date: Thu, 12 Jul 2012 10:21:51 +0100

To: craven@gmx.net, notmuch@notmuchmail.org

Cc:

From: Mark Walters


A couple more things:

On Thu, 12 Jul 2012, craven@gmx.net wrote:
> This patch adds a new type sprinter_t, which is used for structured
> formatting, e.g. JSON or S-Expressions. The structure printer is the
> code from Austin Clements (id:87d34hsdx8.fsf@awakening.csail.mit.edu).
>
> The structure printer contains the following function pointers:
>
> /* start a new map/dictionary structure.
>  */
> void (*begin_map) (struct sprinter *);
>
> /* start a new list/array structure
>  */
> void (*begin_list) (struct sprinter *);
>
> /* end the last opened list or map structure
>  */
> void (*end) (struct sprinter *);

what is the advantage of having this as one function rather than end_map
and end_list? Indeed, my choice (but I think most other people would
disagree) would be to have both functions but still keep state as this
currently does and then throw an error if the code closes the wrong
thing.

A second question: do you have an implementation in this style for
s-expressions. I find it hard to tell whether the interface is right
with just a single example. Even a completely hacky not ready for review
example would be helpful.

Best wishes

Mark

> /* print one string/integer/boolean/null element (possibly inside a
>  * list or map
>  */
> void (*string) (struct sprinter *, const char *);
> void (*integer) (struct sprinter *, int);
> void (*boolean) (struct sprinter *, notmuch_bool_t);
> void (*null) (struct sprinter *);
>
> /* print the key of a map's key/value pair.
>  */
> void (*map_key) (struct sprinter *, const char *);
>
> /* print a frame delimiter (such as a newline or extra whitespace)
>  */
> void (*frame) (struct sprinter *);
>
> The printer can (and should) use internal state to insert delimiters and
> syntax at the correct places.
>
> Example:
>
> format->begin_map(format);
> format->map_key(format, "foo");
> format->begin_list(format);
> format->integer(format, 1);
> format->integer(format, 2);
> format->integer(format, 3);
> format->end(format);
> format->map_key(format, "bar");
> format->begin_map(format);
> format->map_key(format, "baaz");
> format->string(format, "hello world");
> format->end(format);
> format->end(format);
>
> would output JSON as follows:
>
> {"foo": [1, 2, 3], "bar": { "baaz": "hello world"}}
> ---
>  sprinter.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 49 insertions(+)
>  create mode 100644 sprinter.h
>
> diff --git a/sprinter.h b/sprinter.h
> new file mode 100644
> index 0000000..1dad9a0
> --- /dev/null
> +++ b/sprinter.h
> @@ -0,0 +1,49 @@
> +#ifndef NOTMUCH_SPRINTER_H
> +#define NOTMUCH_SPRINTER_H
> +
> +/* for notmuch_bool_t */
> +#include "notmuch-client.h"
> +
> +/* Structure printer interface */
> +typedef struct sprinter
> +{
> +    /* start a new map/dictionary structure.
> +     */
> +    void (*begin_map) (struct sprinter *);
> +
> +    /* start a new list/array structure
> +     */
> +    void (*begin_list) (struct sprinter *);
> +
> +    /* end the last opened list or map structure
> +     */
> +    void (*end) (struct sprinter *);
> +
> +    /* print one string/integer/boolean/null element (possibly inside a
> +     * list or map
> +     */
> +    void (*string) (struct sprinter *, const char *);
> +    void (*integer) (struct sprinter *, int);
> +    void (*boolean) (struct sprinter *, notmuch_bool_t);
> +    void (*null) (struct sprinter *);
> +
> +    /* print the key of a map's key/value pair.
> +     */
> +    void (*map_key) (struct sprinter *, const char *);
> +
> +    /* print a frame delimiter (such as a newline or extra whitespace)
> +     */
> +    void (*frame) (struct sprinter *);
> +} sprinter_t;
> +
> +/* Create a new structure printer that emits JSON */
> +struct sprinter *
> +sprinter_json_new(const void *ctx, FILE *stream);
> +
> +/* A dummy structure printer that signifies that standard text output is
> + * to be used instead of any structured format.
> + */
> +struct sprinter *
> +sprinter_text;
> +
> +#endif // NOTMUCH_SPRINTER_H
> -- 
> 1.7.11.1
>
> _______________________________________________
> notmuch mailing list
> notmuch@notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch

Thread: