Current section

Files

Jump to
gleam_validator gen docs index.html
Raw

gen/docs/index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>validator</title>
<link rel="stylesheet" href="./index.css" type="text/css" />
</head>
<body>
<header class="page-header">
<h2>
validator<!-- - -->
</h2>
</header>
<div class="page">
<nav class="sidebar">
<a class="sidebar-toggle" href="#">
<svg
aria-hidden="true"
focusable="false"
data-prefix="fas"
data-icon="bars"
class="svg-inline--fa fa-bars fa-w-14"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 448 512"
>
<path
fill="#fff"
d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"
></path>
</svg>
</a>
<h2>Pages</h2>
<ul>
<li><a href="./index.html">README</a></li>
</ul>
<h2>Modules</h2>
<ul>
<li><a href="./validator&#x2f;">validator</a></li>
<li><a href="./validator&#x2f;common&#x2f;">validator&#x2f;common</a></li>
<li><a href="./validator&#x2f;int&#x2f;">validator&#x2f;int</a></li>
<li><a href="./validator&#x2f;list&#x2f;">validator&#x2f;list</a></li>
<li><a href="./validator&#x2f;option&#x2f;">validator&#x2f;option</a></li>
<li><a href="./validator&#x2f;string&#x2f;">validator&#x2f;string</a></li>
</ul>
</nav>
<div class="content">
<h1>Validator</h1>
<p>A validation library for <a href="https://gleam.run/">Gleam</a>.</p>
<p>This library follows the principle <a href="https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/">Parse don't validate</a>.</p>
<p>You start with an input type and validate into an output type. These two types can be different. For example:</p>
<pre><code class="language-haskell">type UserInput { UserInput(name: Option(String), age: Int) }
type ValidUser { ValidUser(name: String, age: Int) }
</code></pre>
<p>Then you create a validator like:</p>
<pre><code class="language-haskell">import validator
import validator/common.{ValidatorResult}
import validator/int
import validator/option
fn user_validator(user: UserInput) -&gt; ValidatorResult(ValidUser, String) {
validator.build2(ValidUser)
|&gt; validator.validate(user.name, option.is_some(&quot;Please provide a name&quot;))
|&gt; validator.validate(user.age, int.min(13, &quot;Must be at least 13 years old&quot;))
}
</code></pre>
<p>And run it:</p>
<pre><code class="language-rust">case user_validator(input) {
Ok(valid_user) -&gt; ...
Error(tuple(first_error, all_errors)) -&gt; ...
}
</code></pre>
<h2>Error type</h2>
<p>Errors can be your own type e.g.</p>
<pre><code class="language-haskell">import validator
import validator/common.{ValidatorResult}
import validator/int
import validator/option
type Error {
ErrorEmptyName,
ErrorTooYoung,
}
fn user_validator(user: UserInput) -&gt; ValidatorResult(ValidUser, String) {
validator.build2(ValidUser)
|&gt; validator.validate(user.name, option.is_some(ErrorEmptyName))
|&gt; validator.validate(user.age, int.min(13, ErrorTooYoung))
}
</code></pre>
<h2>ValidatorResult</h2>
<p><code>ValidatorResult(valid, error)</code> is an alias for <code>Result(valid, tuple(error, List(error)))</code></p>
<p>The <code>Ok</code> branch has the valid output.</p>
<p>The <code>Error</code> branch has a tuple <code>tuple(error, List(error))</code>.
The first value is the first error. The second value is a list with all errors (including the first).</p>
<h2>Custom property validator</h2>
<p>A property validator has two components:</p>
<ul>
<li>The error to return</li>
<li>A function that transforms the property if successful (<code>fn(input) -&gt; Option(output)</code>)</li>
</ul>
<p>Example:</p>
<pre><code class="language-rust">fn bigger_than_10(num: Int) -&gt; Option(num) {
case num &gt; 10 {
True -&gt;
Some(num)
False -&gt;
None
}
}
let custom = validator.custom(&quot;Must be bigger than 10&quot;, bigger_than_10)
let validator = fn(form: FormInput) {
validator.build1(ValidForm)
|&gt; validator.validate(form.quantity, custom)
}
</code></pre>
<h2>Test</h2>
<pre><code class="language-sh">rebar3 compile
rebar3 eunit
</code></pre>
<h2>Installation</h2>
<p>This package can be installed by adding <code>gleam_validator</code> to your <code>rebar.config</code> dependencies:</p>
<pre><code class="language-erlang">{deps, [
gleam_validator
]}.
</code></pre>
</div>
</div>
<footer class="pride" onclick="document.querySelector('.pride').classList.toggle('show')">
<div class="blue">Lucy</div>
<div class="pink">says</div>
<div class="white">trans</div>
<div class="pink">rights</div>
<div class="blue"></div>
<a></a>
</footer>
</body>
</html>