Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

define-json-mapping allows nonsensical key subforms #79

Open
LiberalArtist opened this issue May 18, 2022 · 0 comments
Open

define-json-mapping allows nonsensical key subforms #79

LiberalArtist opened this issue May 18, 2022 · 0 comments

Comments

@LiberalArtist
Copy link

I recently wrote something like the following buggy code:

(define-json-mapping <project-info> make-project-info project-info?
  json->project-info
  (license project-info-license
           (lambda (x)
             (if (string? x)
                 (spdx-string->license x)
                 #f))))

and was confused to find that project-info-license always produced *unspecified*.

Eventually, I worked out that I needed instead to write:

(define-json-mapping <project-info> make-project-info project-info?
  json->project-info
  (license project-info-license
           "license" (lambda (x)
                       (if (string? x)
                           (spdx-string->license x)
                           #f))))

i.e. that writing "license" was required even though it matched license.

Originally, I had read the grammar at:

guile-json/README.md

Lines 331 to 348 in 81bc5da

- *((field getter ...) ...)* : a series of field specifications.
- *field* : the name of a JSON object field.
- *getter* : the name of the procedure to get the value of this field
given a record of this type.
- *key* : a different name for the field of this JSON object. If given, this
name will be used instead of the field name when serializing or
deserializing.
- *scm->value* : an optional procedure that will be used to convert native
values supported by guile-json to the value contained in the record. Used
when reading JSON.
- *value->scm* : an optional procedure that will be used to convert the
value contained in the record to a native value supported by guile-json
Used when writing JSON.

to mean the field and getter subforms were required, but the key, scm->value, and value->scm subforms were optional, so I thought I would only need to specify key if it were different than field. However, it seems like what I intended as a scm->value expression was being treated as a key, and of course there would never be a key equal? to that procedure, so I ended up with *unspecified* and no scm->value procedure to convert it.

I can see a few possible improvements, depending on what behavior is preferred:

  1. If you want key to be optional in the way I originally imagined:

    1. The expansion of define-json-mapping could check at run-time if the first of the optional sub-forms evaluates to a string and treat it as key if so; scm->value otherwise.

    2. If key is restricted to a string literal, rather than an expression that evaluates to a string, define-json-mapping could perform such a check at compile-time.

  2. If you want key to be required in order to provide scm->value, I think define-json-mapping should still check, either at run-time or compile-time, that key actually is/evaluates to a string, since supplying a procedure for key would never be a reasonable thing to do.

@LiberalArtist LiberalArtist changed the title define-json-mapping allows nonsensical key subforms define-json-mapping allows nonsensical key subforms May 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants