• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

How to check the structure of a Map

 
Sheriff
Posts: 5555
326
IntelliJ IDE Python Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm using compojure to put together a RESTful service. I have a PUT route configured that takes some json as the request body and I've captured that data and have it represented as a map (using cheshire for the translation).

So input

becomes clojure map
All lovely so far. Now here's the question:

What is the easiest way to perform some validation on the structure of the map? In this example I would want to verify that the map contains the keyword :foo. I'm not too concerned if there's extra other keywords in the map but I would want to know if an expected keyword is not present, say if the service user misspelled "foo" and :fooo was received instead of :foo.

I know I could achieve this with a series of accessor functions but aside from it being a bit tedious I would be easily tripped up by a valid key whose value is nil as you also get a nil when asking for a key that doesn't exist. For example (using a repl)
Asking for a valid key that has a value nil and asking for a non present key look the same.

Any suggestions on how I might achieve this neatly?
 
Tim Cooke
Sheriff
Posts: 5555
326
IntelliJ IDE Python Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Having spent the afternoon digging around on this I have arrived at a solution. As I suspected I am not the first person in the world to face this issue and have found a lovely little library called Schema. As the name alludes to, Schema allows you to define a schema for arbitrary data structures including maps. Let's look at my example again. I want to verify that my map contains the key :foo. I can create a schema that describes a single item map with key :foo and value of type String:

Now I can use that data structure (schema) to validate any map

Splendid!
 
Rancher
Posts: 379
22
Mac OS X Monad Clojure Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I was going to suggest Schema - it's an excellent run time validation library.

In the language itself, you might want to look :pre and :post condition checking for functions (argument and result value assertions).

Another interesting option is core.typed but that's more for (static) type checking of your code's consistency, not for validating that user input matches a particular structure. It you could declare a ValidatedData type and annotate your code, post-validation, with that and core.typed could verify that your code is "safe" in terms of consistent usage of the data structures (e.g., if you declare that :foo is :mandatory in a ValidatedData object, then doing (:foo valid-data) is never going to return nil so your code wouldn't need to check for it in order to be "type safe").

We started using Schema at World Singles, but you need good tests to exercise all of the run time checks. We switched to core.typed but it's hard work since you must satisfy a full static type checker and some Clojure idioms (such as nil-punning) can make that very hard to work with.
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic