Skip to content

Commit

Permalink
Version 3
Browse files Browse the repository at this point in the history
  • Loading branch information
sporto committed Jun 29, 2024
1 parent 429622c commit 8e7eee7
Show file tree
Hide file tree
Showing 5 changed files with 256 additions and 131 deletions.
24 changes: 23 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,29 @@
# Changelog

### 3.0.0

### Changed

- function `validate` renamed to `check`

### Added

- Most checks have an `and_` version. E.g. `and_string_is_int`
- check `ok`
- check `optional_in_dict`
- check `optional_in`
- check `required_in_dict`
- check `required_in`

## 2.0.0

### Changed

- All functions moved to main `valid` module.
- Remove all other sub modules

## 0.2.0

### Changed

- Refactor list.every so it works with nested validators
- Refactor list.every so it works with nested validators
33 changes: 27 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ import valid.{type ValidatorResult}
fn user_validator(user: UserInput) -> ValidatorResult(ValidUser, String) {
valid.build2(ValidUser)
|> valid.validate(user.name, valid.is_some("Please provide a name"))
|> valid.validate(user.age, valid.int_min(13, "Must be at least 13 years old"))
|> valid.check(user.name, valid.is_some("Please provide a name"))
|> valid.check(user.age, valid.int_min(13, "Must be at least 13 years old"))
}
```

Expand All @@ -59,8 +59,8 @@ type Error {
fn user_valid(user: UserInput) -> ValidatorResult(ValidUser, String) {
valid.build2(ValidUser)
|> valid.validate(user.name, valid.is_some(ErrorEmptyName))
|> valid.validate(user.age, valid.int_min(13, ErrorTooYoung))
|> valid.check(user.name, valid.is_some(ErrorEmptyName))
|> valid.check(user.age, valid.int_min(13, ErrorTooYoung))
}
```

Expand All @@ -71,11 +71,12 @@ fn user_valid(user: UserInput) -> ValidatorResult(ValidUser, String) {
The `Ok` branch has the valid output.

The `Error` branch has a tuple `tuple(error, List(error))`.

The first value is the first error. The second value is a list with all errors (including the first).

## Validators

See the [API Docs](https://hexdocs.pm/valid/) for the list of included valids.
See the [API Docs](https://hexdocs.pm/valid/) for the list of included validators.

## Custom property validator

Expand Down Expand Up @@ -103,7 +104,27 @@ let custom = valid.custom("Must be bigger than 10", bigger_than_10)
let valid = fn(form: FormInput) {
valid.build1(ValidForm)
|> valid.validate(form.quantity, custom)
|> valid.check(form.quantity, custom)
}
```

## Validating a Dictionary

Use `required_in_dict` and `optional_in_dict`

```gleam
fn user_validator(dictionary: Dict(String, String)) {
valid.build2(ValidUser)
|> valid.check(
dictionary,
valid.required_in_dict("name", "Missing name")
|> valid.and_string_is_not_empty("Please provide a name"),
)
|> valid.check(
input,
valid.optional_in_dict("age")
|> valid.and_optional(valid.string_is_int("Please provide a valid number")),
)
}
```

Expand Down
26 changes: 26 additions & 0 deletions docs/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Design

## Why not use `use`?

```gleam
use name <- valid.try(name_validator)
use email <- valid.try(email_validator)
```

Looks nice, but the fact that this would short circuit at the first failed validator, means that we cannot collect all errors.

## What if steps in the pipeline imply `and`?

```gleam
let name_validator =
|> valid.ok
|> valid.string_is_not_empty("Empty")
|> valid.string_min_length("More", 6)
|> valid.string_max_length("Less", 2)
```

This would be nice, as we could get rid of `and`.

Each step in the pipeline would return a function that expected the previous validator.

However `list_all` is an issue.
Loading

0 comments on commit 8e7eee7

Please sign in to comment.