[ANN] Announcing validate 1.0.0 - Enhanced Data Validation in OCaml!

Hello OCaml Community!

I’m excited to share the release of validate version 1.0.0 with you all! This version is a significant milestone in my journey to provide a robust data validation library for OCaml.

In this release, I’ve introduced some exciting features. Variant support is now available, enabling more complex data types to be handled with ease. I’ve also implemented support for recursive and circular recursive types, allowing validation of nested and interconnected data structures. Here’s a quick peek at how it works:

type tree =
  | Leaf of (int[@greater_than 0])
  | Node of { 
    (*Annotation can be on type or label declaration, both works*)
    left : tree; [@dive] 
    right : (tree[@dive])
  } [@@deriving validate, show, eq]

let my_tree = Node { left = Leaf 1; right = Leaf 2 }
let validation_result = validate_tree my_tree

I’m also excited to announce that the validate API is now stable. While I plan to keep enhancing the library by adding new annotations for different validators over time, I assure you of consistent and reliable functionality in future updates.

If you have suggestions for new validators or features, we’d love to hear them. Your feedback is crucial in shaping the future of validate .

To dive deeper into validate 1.0.0, check out our GitHub page: GitHub - Axot017/validate: OCaml ppx deriver designed to streamline the process of validating records.

Happy Coding!

16 Likes

Hey everyone, it’s me again with more good news from the validate world!

I’m thrilled to announce that validate has just leveled up to version 1.1.0! This update packs a bunch of new features and annotations that I’m sure you’ll find useful.

What’s New:

  • New String Annotations: @ulid for ULID strings, @ipv4 and @ipv6 for IP addresses, @phone for E.164 phone numbers, and @mac_address for MAC addresses. These will help ensure your data formats are spot on.
  • Option Type Annotations: Introducing @some and @none to assert presence or absence of values in option types.
  • Advanced Annotations:
    • @custom: Create your own validation logic! It’s super flexible and allows you to define validations that suit your unique needs.
    • @ignore_if: Skip validations conditionally. Really handy for those complex data structures.
    • @some_if and @none_if: Control the requirements of Some and None in option types based on conditions.

Dive into the Examples:

@custom

let custom_validator str =
  if String.length str > 1 then Ok ()
  else Error (Validate.BaseError { code = "custom_validator"; params = [] })

type custom_validator_record = {
  custom_validator : string; [@custom custom_validator]
  ...
}
[@@deriving validate]

@ignore_if

type temperature_record = {
  unit : string;
  temperature : int; [@greater_than_or_equal 0] [@ignore_if fun r -> r.unit <> "K"]
}
[@@deriving validate]

@some_if and @none_if

type contact_info = {
  username : string option; [@some_if fun r -> r.email = None]
  email : string option; [@none_if fun r -> Option.is_some r.username]
}
[@@deriving validate]

These new features add so much more depth and flexibility to validate. I’m really excited to see how you all use them in your projects.

Check out all the details: GitHub - Axot017/validate.

4 Likes

Just to let you know that a lot of work has been done on IPv4 and IPv6 as well as email addresses. In my experience (and from what I’ve been able to learn about email addresses), it’s not advisable to use regexps to validate a string because the formats are so subtly complex.

6 Likes

I was curious so I ported the tests to test against validate. The code and output can be found in this gist dune · GitHub

All the bad emails were correctly rejected. Of the 184 valid emails 134 were incorrectly rejected.

The validate package has an ocaml>=5.0.0, but cloning the repo it builds fine and the tests pass under 4.14.1. The above test was run under OCaml 5.1.0 though.

1 Like

@dinosaure I’m fully aware that emails can be complex, and it’s not feasible (or exceedingly difficult) to validate them solely with regex. Despite this, I opted to use regexes because I believe they are sufficient for the average use case and, in some situations, even more desirable than more comprehensive validation methods. For example, when validating a login form, I wouldn’t consider Undisclosed recipients:; a valid email, even though, technically, it is.

That being said, I was previously unaware of the existing libraries dedicated to parsing IPs and emails. This revelation has certainly piqued my interest, and I plan to explore them further when I have some free time.

The tests conducted by @reynir have been eye-opening, demonstrating that a significant number of emails, which are in fact valid, are deemed invalid by the current approach. As a response to this, I’m considering the introduction of a new annotation in the upcoming version. This annotation will leverage emile behind the scenes to validate emails for developers in need of 100% accuracy. However, I intend to keep the existing validation mechanism as it is, believing it to meet the needs of most use cases adequately.

Thank you for your invaluable feedback, @dinosaure, for sharing these awesome packages, and @reynir, for the effort you’ve put into testing this.

2 Likes