-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
validate types/schemas inside other schemas? #44
Comments
Hey James! Thank you :) I'll be improving Validator protocol so that it can be used to validate contracts too, so yes, you'll be able to re-use a contract in another contract's schema, ie: defmodule UserContract do
# ...
end
defmodule AccountContract do
schema do
%{user: UserContract}
end
end Notice that types can be already validated individually too using the protocol, but it's a bit cumbersome to do because you need to create type structs manually at the moment (I'll make it nicer eventually): defmodule Email do
use Drops.Type, string(:filled?)
end
import Drops.Type.Validator
validate(Email.new([]), "[email protected]")
# {:ok, "[email protected]"}
validate(Email.new([]), 312)
# {:error, [input: 312, predicate: :type?, args: [:string, 312]]}
validate(Email.new([]), "")
# {:error, [input: "", predicate: :filled?, args: [""]]} |
Wow, thanks for the prompt reply! The proposed re-use contract feature looks perfect, can't wait. Until then, thanks for the trick validating a type by itself. I'd tried to figure it out from the source but couldn't quite get it.. thanks again! |
Oh that's not a good sign. This is the very first iteration of the validator protocol and types, so the code could be simplified. Could you tell me which parts were confusing for you? Thanks! |
Sorry for the late reply, was pulled away. Oh it's not a code problem I'm sure. I was in a big hurry and had only the most cursory look. I tend to just look at the tests to see what's "possible" and if there's nothing there, assume it's not.. I do have one follow-up question which is probably going to be important to many. How do you envisage this fitting in with pattern matching? I like to build rudimentary "type checking" into function signatures all over the place just as a sanity check. We can currently use this checking pre-conform, but I think it's most useful post-conform, and currently conform spits out a raw map. For now I'm working around this with basically a secondary struct which i construct from the post-conform, but obviously that's a bit of a hack. Or is this way outside your envisaged use case 😅 An alternative approach could be to store the "full" struct elsewhere and leave a usable, keys-only struct available for struct, like https://github.com/saleyn/typedstruct does. Unfortunately it's currently impossible to use both, as Drops.Contract expects new/2 to exist. |
@jtippett generating type-safe structs is on the roadmap. I'm probably going to add a way of inferring a typed struct from a schema definition and that should be enough, something like: defmodule UserContract do
use Drops.Contract
schema do
%{required(:name) => string()}
end
end
defmodule User do
use Drops.Struct
defstruct_from_schema(UserContract)
end |
Firstly, thanks for this awesome library. Big fan of dry-rb and great to see you in elixir-land!
I'm curious about one thing - it would be ideal to be able to individually create/validate subschemas/types, a little more than pure maps so I can add more checks around the place prior to validating the "master" contract. I have previously used DB-less Ecto quite a bit for this, or just pattern matching on structs at the argument level.
It would be helpful to be able to either call "conform" on a type, or otherwise use a structs-like interface to be able to create/match on types. Either that or make a contract embed-able into another.
Any plans (or recommendations) along these lines?
Thanks once again.
The text was updated successfully, but these errors were encountered: