Skip to content

Commit

Permalink
Feature: declarative schemas (#3)
Browse files Browse the repository at this point in the history
* Add test system to sanity-clause.asd

* Add schema-spec loader

* Bump version to 0.2.0

* Update docs for schema specs
  • Loading branch information
fisxoj authored Nov 18, 2018
1 parent cbe35dc commit 873c34c
Show file tree
Hide file tree
Showing 19 changed files with 218 additions and 195 deletions.
16 changes: 9 additions & 7 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,30 @@
<table class="docinfo" frame="void" rules="none"><col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author</th><td>Matt Novenstern</td></tr><tr><th class="docinfo-name">Version</th><td>0.2.0</td></tr><tr class="field"><th colspan="1" class="docinfo-name">license:</th><td class="field-body">LLGPLv3+</td>
<tr><th class="docinfo-name">Author</th><td>Matt Novenstern</td></tr><tr><th class="docinfo-name">Version</th><td>0.3.0</td></tr><tr class="field"><th colspan="1" class="docinfo-name">license:</th><td class="field-body">LLGPLv3+</td>
</tr>
</tbody>
</table>
<p>Sanity clause is a data validation/contract library that can be used to collect and validate information. You might use it for configuration data, or validating data from an api response, or documents from a datastore.</p>
<p>To make use of it, you define schemas, which are currently property lists with <a class="reference ref-class" href="sanity-clause.field.html#class-field"><span class="ref-class">sanity-clause.field:field</span></a> subclasses that dictate the type of values you expect as well as the shape of the property list to be returned after deserializing and validating data.</p>
<p>To make use of it, you define schemas, which are currently property lists with <a class="reference ref-class" href="sanity-clause.field.html#class__field"><span class="ref-class">sanity-clause.field:field</span></a> subclasses that dictate the type of values you expect as well as the shape of the property list to be returned after deserializing and validating data.</p>
<p>Eventually, there will be an interface that allows creating schemas attached to classes, so that you can deserialize data directly into a class instance.</p>
<div id="packages" class="section"><h2><a name="packages">Packages</a></h2>
<ul>
<li><p class="first last"><a class="reference" href="sanity-clause.html"><span>sanity-clause</span></a></p>
<li><p class="first last"><a class="reference" href="sanity-clause.util.html"><span>sanity-clause.util</span></a></p>
</li>
<li><p class="first last"><a class="reference" href="sanity-clause.validator.html"><span>sanity-clause.validator</span></a></p>
</li>
<li><p class="first last"><a class="reference" href="sanity-clause.field.html"><span>sanity-clause.field</span></a></p>
</li>
<li><p class="first last"><a class="reference" href="sanity-clause.serde.html"><span>sanity-clause.serde</span></a></p>
<li><p class="first last"><a class="reference" href="sanity-clause.schema.html"><span>sanity-clause.schema</span></a></p>
</li>
<li><p class="first last"><a class="reference" href="sanity-clause.util.html"><span>sanity-clause.util</span></a></p>
<li><p class="first last"><a class="reference" href="sanity-clause.serde.html"><span>sanity-clause.serde</span></a></p>
</li>
<li><p class="first last"><a class="reference" href="sanity-clause.validator.html"><span>sanity-clause.validator</span></a></p>
<li><p class="first last"><a class="reference" href="sanity-clause.html"><span>sanity-clause</span></a></p>
</li>
</ul>
</div>
<hr class ="docutils footer" /><div class="footer">Generated on : Thu, 15 Nov 2018 17:24:20 .
<hr class ="docutils footer" /><div class="footer">Generated on : Sun, 18 Nov 2018 17:35:20 .
Generated by cl-docutils 0.1.1 from <a class="reference" href="http://docutils.sourceforge.net/rst.html"><span>restructured text</span></a> source.
</div>
</div>
Expand Down
158 changes: 63 additions & 95 deletions docs/sanity-clause.field.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,104 +8,72 @@
<body>
<div id="sanity-clause-field-package" class="document"><h1 class="title">sanity-clause.field package</h1>
<p>Field classes that can be used to validate data.</p>
<p>Also contains <a class="reference ref-function" href="sanity-clause.field.html#function-get-value"><span class="ref-function">get-value</span></a>, <a class="reference ref-function" href="sanity-clause.field.html#function-deserialize"><span class="ref-function">deserialize</span></a>, and <a class="reference ref-function" href="sanity-clause.field.html#function-validate"><span class="ref-function">validate</span></a>, which represent the lifecycle of loading data from some other object.</p>
<div id="classes" class="section"><h2><a name="classes">Classes</a></h2>
<a id="class-field" class="target" name="class-field"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">field</span></tt></dt>
<dd>A base class for all fields that controls how they are (de?)serialized.</dd>
</dl>
<a id="class-required-value-error" class="target" name="class-required-value-error"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">required-value-error</span></tt></dt>
<dd>An error that signals a required value is missing.</dd>
</dl>
<a id="class-string-field" class="target" name="class-string-field"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">string-field</span></tt></dt>
<dd>A field that contains a string.</dd>
</dl>
<a id="class-uuid-field" class="target" name="class-uuid-field"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">uuid-field</span></tt></dt>
<dd>A field for values that should resemble UUIDs.</dd>
</dl>
<a id="class-integer-field" class="target" name="class-integer-field"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">integer-field</span></tt></dt>
<dd>A field that holds an integer value.</dd>
</dl>
<a id="class-constant-field" class="target" name="class-constant-field"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">constant-field</span></tt></dt>
<dd>A field that expects to get the same value every time. Will throw a <a class="reference ref-class" href="sanity-clause.field.html#class-conversion-error"><span class="ref-class">conversion-error</span></a> if VALUE isn't equal to CONSTANT according to TEST.</dd>
</dl>
<a id="class-conversion-error" class="target" name="class-conversion-error"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">conversion-error</span></tt></dt>
<dd>An error that signals something went wrong while calling <tt class="docutils literal">
<span class="pre">converter</span></tt> for a field.</dd>
</dl>
<a id="class-member-field" class="target" name="class-member-field"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">member-field</span></tt></dt>
<dd>A field that expects a member of a set of symbols.</dd>
</dl>
<a id="class-boolean-field" class="target" name="class-boolean-field"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">boolean-field</span></tt></dt>
<dd>A field type for bolean values.</dd>
</dl>
<a id="class-validation-error" class="target" name="class-validation-error"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">validation-error</span></tt></dt>
<dd>Error that indicates a field is invalid.</dd>
</dl>
<a id="class-real-field" class="target" name="class-real-field"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">real-field</span></tt></dt>
<dd>A field that contains a real value (eg. possibly a float).</dd>
</dl>
<a id="class-email-field" class="target" name="class-email-field"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">email-field</span></tt></dt>
<dd>A field for values that should be emails.</dd>
</dl>
<a id="class-timestamp-field" class="target" name="class-timestamp-field"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">timestamp-field</span></tt></dt>
<dd>A field that contains a timestamp</dd>
</dl>
</div>
<p>Also contains <a class="reference ref-function" href="sanity-clause.field.html#function__get-value"><span class="ref-function">get-value</span></a>, <a class="reference ref-function" href="sanity-clause.field.html#function__deserialize"><span class="ref-function">deserialize</span></a>, and <a class="reference ref-function" href="sanity-clause.field.html#function__validate"><span class="ref-function">validate</span></a>, which represent the lifecycle of loading data from some other object.</p>
<div id="functions" class="section"><h2><a name="functions">Functions</a></h2>
<a id="function-get-value" class="target" name="function-get-value"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">get-value</span></tt></dt>
<dd>Tries to fetch the value corresponding to the field from some datastructure. <tt class="docutils literal param">
<span class="pre">field-name</span></tt> is used if no attribute is explicitly set on the field.</dd>
</dl>
<a id="function-deserialize" class="target" name="function-deserialize"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">deserialize</span></tt></dt>
<dd>Converts the value retrieved from the raw data into the datatype the field expects to work with, or fails, raising a <a class="reference ref-class" href="sanity-clause.field.html#class-conversion-error"><span class="ref-class">conversion-error</span></a>.</dd>
</dl>
<a id="function-dump-field-p" class="target" name="function-dump-field-p"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">dump-field-p</span></tt></dt>
<dd>Is this field required for serialization (fields that have flow of :dump or :both)?</dd>
</dl>
<a id="function-attribute-of" class="target" name="function-attribute-of"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">attribute-of</span></tt></dt>
<dd>NIL</dd>
</dl>
<a id="function-error-messages-of" class="target" name="function-error-messages-of"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">error-messages-of</span></tt></dt>
<dd>NIL</dd>
</dl>
<a id="function-load-field-p" class="target" name="function-load-field-p"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">load-field-p</span></tt></dt>
<dd>Is this field required for deserialization (fields that have flow of :load or :both)?</dd>
</dl>
<a id="function-make-field" class="target" name="function-make-field"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">make-field</span></tt></dt>
<dd>Make a field instance of class <tt class="docutils literal">
<a id="function-make-field" class="target" name="function-make-field"></a><p><tt class="docutils literal">
<span class="pre">make-field</span> <span class="pre">(type</span> <span class="pre">&amp;rest</span> <span class="pre">args)</span></tt></p>
<p>Make a field instance of class <tt class="docutils literal">
<span class="pre">type-FIELD</span></tt> and give it initargs <tt class="docutils literal param">
<span class="pre">args</span></tt>.</dd>
</dl>
<a id="function-data-key-of" class="target" name="function-data-key-of"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">data-key-of</span></tt></dt>
<dd>NIL</dd>
</dl>
<a id="function-validate" class="target" name="function-validate"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">validate</span></tt></dt>
<dd>Run the validation checks for a given field and raise a <a class="reference ref-class" href="sanity-clause.field.html#class-validation-error"><span class="ref-class">validation-error</span></a> if it is invalid.</dd>
</dl>
<span class="pre">args</span></tt>.</p>
<a id="function-dump-field-p" class="target" name="function-dump-field-p"></a><p><tt class="docutils literal">
<span class="pre">dump-field-p</span> <span class="pre">(field)</span></tt></p>
<p>Is this field required for serialization (fields that have flow of :dump or :both)?</p>
<a id="function-load-field-p" class="target" name="function-load-field-p"></a><p><tt class="docutils literal">
<span class="pre">load-field-p</span> <span class="pre">(field)</span></tt></p>
<p>Is this field required for deserialization (fields that have flow of :load or :both)?</p>
</div>
<div id="generic-functions" class="section"><h2><a name="generic-functions">Generic Functions</a></h2>
<a id="generic-function-get-value" class="target" name="generic-function-get-value"></a><p><tt class="docutils literal">
<span class="pre">get-value</span> <span class="pre">(FIELD</span> <span class="pre">OBJECT</span> <span class="pre">&amp;OPTIONAL</span> <span class="pre">FIELD-NAME)</span></tt> Tries to fetch the value corresponding to the field from some datastructure. <tt class="docutils literal param">
<span class="pre">field-name</span></tt> is used if no attribute is explicitly set on the field. .. _generic-function__validate:</p>
<p><tt class="docutils literal">
<span class="pre">validate</span> <span class="pre">(FIELD</span> <span class="pre">VALUE)</span></tt> Run the validation checks for a given field and raise a <a class="reference ref-class" href="sanity-clause.field.html#class__validation-error"><span class="ref-class">validation-error</span></a> if it is invalid. .. _generic-function__deserialize:</p>
<p><tt class="docutils literal">
<span class="pre">deserialize</span> <span class="pre">(FIELD</span> <span class="pre">VALUE)</span></tt> Converts the value retrieved from the raw data into the datatype the field expects to work with, or fails, raising a <a class="reference ref-class" href="sanity-clause.field.html#class__conversion-error"><span class="ref-class">conversion-error</span></a>.</p>
</div>
<div id="classes" class="section"><h2><a name="classes">Classes</a></h2>
<a id="condition-required-value-error" class="target" name="condition-required-value-error"></a><p><tt class="docutils literal">
<span class="pre">required-value-error</span></tt></p>
<p>An error that signals a required value is missing. .. _condition__conversion-error:</p>
<p><tt class="docutils literal">
<span class="pre">conversion-error</span></tt></p>
<p>An error that signals something went wrong while calling <tt class="docutils literal">
<span class="pre">converter</span></tt> for a field. .. _condition__validation-error:</p>
<p><tt class="docutils literal">
<span class="pre">validation-error</span></tt></p>
<p>Error that indicates a field is invalid. .. _class__timestamp-field:</p>
<p><tt class="docutils literal">
<span class="pre">timestamp-field</span></tt></p>
<p>A field that contains a timestamp .. _class__real-field:</p>
<p><tt class="docutils literal">
<span class="pre">real-field</span></tt></p>
<p>A field that contains a real value (eg. possibly a float). .. _class__integer-field:</p>
<p><tt class="docutils literal">
<span class="pre">integer-field</span></tt></p>
<p>A field that holds an integer value. .. _class__constant-field:</p>
<p><tt class="docutils literal">
<span class="pre">constant-field</span></tt></p>
<p>A field that expects to get the same value every time. Will throw a <a class="reference ref-class" href="sanity-clause.field.html#class__conversion-error"><span class="ref-class">conversion-error</span></a> if VALUE isn't equal to CONSTANT according to TEST. .. _class__uuid-field:</p>
<p><tt class="docutils literal">
<span class="pre">uuid-field</span></tt></p>
<p>A field for values that should resemble UUIDs. .. _class__email-field:</p>
<p><tt class="docutils literal">
<span class="pre">email-field</span></tt></p>
<p>A field for values that should be emails. .. _class__boolean-field:</p>
<p><tt class="docutils literal">
<span class="pre">boolean-field</span></tt></p>
<p>A field type for bolean values. .. _class__member-field:</p>
<p><tt class="docutils literal">
<span class="pre">member-field</span></tt></p>
<p>A field that expects a member of a set of symbols. .. _class__string-field:</p>
<p><tt class="docutils literal">
<span class="pre">string-field</span></tt></p>
<p>A field that contains a string. .. _class__field:</p>
<p><tt class="docutils literal">
<span class="pre">field</span></tt></p>
<p>A base class for all fields that controls how they are (de?)serialized.</p>
</div>
<hr class ="docutils footer" /><div class="footer">Generated on : Thu, 15 Nov 2018 17:24:20 .
<hr class ="docutils footer" /><div class="footer">Generated on : Sun, 18 Nov 2018 17:35:20 .
Generated by cl-docutils 0.1.1 from <a class="reference" href="http://docutils.sourceforge.net/rst.html"><span>restructured text</span></a> source.
</div>
</div>
Expand Down
21 changes: 3 additions & 18 deletions docs/sanity-clause.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<body>
<div id="sanity-clause-package" class="document"><h1 class="title">sanity-clause package</h1>
<p>Main package of the <a class="reference ref-package" href="sanity-clause.html"><span class="ref-package">sanity-clause</span></a> system.</p>
<p><a class="reference ref-package" href="sanity-clause.html"><span class="ref-package">sanity-clause</span></a> helps define data contracts like "this field will always have a valid integer greater than zero in it". It's also useful for serializing and deserializing data to and from different formats. Contracts are built in the form of schemas, which are composed of <a class="reference ref-class" href="sanity-clause.field.html#class-field"><span class="ref-class">sanity-clause.field:field</span></a> s.</p>
<p><a class="reference ref-package" href="sanity-clause.html"><span class="ref-package">sanity-clause</span></a> helps define data contracts like "this field will always have a valid integer greater than zero in it". It's also useful for serializing and deserializing data to and from different formats. Contracts are built in the form of schemas, which are composed of <a class="reference ref-class" href="sanity-clause.field.html#class__field"><span class="ref-class">sanity-clause.field:field</span></a> s.</p>
<p>for example:</p>
<pre class="literal-block">
(setq schema (list :name (make-field 'string)
Expand All @@ -22,23 +22,8 @@
;; note: the string for age got converted by DESERIALIZE from a string to an integer.
</pre><p>To learn more about what fields exist, check out <a class="reference ref-package" href="sanity-clause.field.html"><span class="ref-package">sanity-clause.field</span></a>.</p>
<p>To see more validation functions, check out <a class="reference ref-package" href="sanity-clause.validator.html"><span class="ref-package">sanity-clause.validator</span></a>.</p>
<div id="functions" class="section"><h2><a name="functions">Functions</a></h2>
<a id="function-make-field" class="target" name="function-make-field"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">make-field</span></tt></dt>
<dd>Make a field instance of class <tt class="docutils literal">
<span class="pre">type-FIELD</span></tt> and give it initargs <tt class="docutils literal param">
<span class="pre">args</span></tt>.</dd>
</dl>
<a id="function-load" class="target" name="function-load"></a><dl class="docutils"><dt><tt class="docutils literal">
<span class="pre">load</span></tt></dt>
<dd>Deserializes <tt class="docutils literal param">
<span class="pre">data</span></tt> into an instance of <tt class="docutils literal param">
<span class="pre">schema</span></tt>. Fills in default values and validates fields. If <tt class="docutils literal param">
<span class="pre">schema</span></tt> is <tt class="docutils literal">
<span class="pre">:env</span></tt>, it will try to load from environment variables.</dd>
</dl>
</div>
<hr class ="docutils footer" /><div class="footer">Generated on : Thu, 15 Nov 2018 17:24:20 .
<p>To see how to load a schema from a file or keyword spec, check out <a class="reference ref-package" href="sanity-clause.schema.html"><span class="ref-package">sanity-clause.schema</span></a>.</p>
<hr class ="docutils footer" /><div class="footer">Generated on : Sun, 18 Nov 2018 17:35:20 .
Generated by cl-docutils 0.1.1 from <a class="reference" href="http://docutils.sourceforge.net/rst.html"><span>restructured text</span></a> source.
</div>
</div>
Expand Down
Loading

0 comments on commit 873c34c

Please sign in to comment.