-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds a validate method and a basic set of constraints.
- Loading branch information
Showing
7 changed files
with
402 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,3 @@ | ||
# Compiled Object files | ||
*.o | ||
*.obj | ||
|
||
# Compiled Dynamic libraries | ||
*.so | ||
*.dylib | ||
*.dll | ||
|
||
# Compiled Static libraries | ||
dutils-validation-test-library | ||
*.a | ||
*.lib | ||
|
||
# Executables | ||
*.exe | ||
|
||
# DUB | ||
.dub | ||
docs.json | ||
__dummy.html | ||
docs/ | ||
|
||
# Code coverage | ||
*.lst |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
language: d | ||
|
||
branches: | ||
only: | ||
- master |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,34 @@ | ||
# validation | ||
|
||
[![DUB Package](https://img.shields.io/dub/v/dutils-validation.svg)](https://code.dlang.org/packages/dutils-validation) | ||
[![Posix Build Status](https://travis-ci.org/d-utils/validation.svg?branch=master)](https://travis-ci.org/d-utils/validation) | ||
|
||
Validation annotations for dlang structs | ||
|
||
## example | ||
|
||
import dutils.validation.constraints : ValidateRequired, ValidateEmail | ||
|
||
struct Email { | ||
@ValidateRequired() | ||
@ValidateEmail() | ||
string to; | ||
|
||
@ValidateRequired() | ||
@ValidateEmail() | ||
string from; | ||
|
||
@ValidateMinimumLength(3) | ||
@ValidateMaximumLength(100) | ||
string subject; | ||
|
||
string body; | ||
} | ||
|
||
auto email = Email("badto.address", "name@example.com", "no", "some body"); | ||
|
||
validate(email); // throws an instance of ValidationErrors | ||
|
||
## TODO | ||
|
||
- [ ] Support for nested structs and arrays |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"name": "dutils-validation", | ||
"description": "Validation annotations for dlang structs", | ||
"homepage": "https://github.com/d-utils/validation", | ||
"authors": [ | ||
"Fredrik Söderström" | ||
], | ||
"copyright": "Copyright © 2020, Fredrik Söderström", | ||
"license": "MIT", | ||
"targetType": "library" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
module dutils.validation.constraints; | ||
|
||
import std.conv : to; | ||
import std.typecons : Nullable; | ||
|
||
import dutils.validation.validate : ValidationError; | ||
|
||
struct ValidateRequired { | ||
Nullable!ValidationError getError(T)(T value, string path) { | ||
if (value) { | ||
return Nullable!ValidationError.init; | ||
} | ||
|
||
return Nullable!ValidationError(ValidationError(path, | ||
ValidationErrorTypes.required, "Required to have a value")); | ||
} | ||
} | ||
|
||
struct ValidateEmail { | ||
Nullable!ValidationError getError(string value, string path) { | ||
import dutils.validation.email : isValidEmail; | ||
|
||
if (isValidEmail(value)) { | ||
return Nullable!ValidationError.init; | ||
} | ||
|
||
return Nullable!ValidationError(ValidationError(path, | ||
ValidationErrorTypes.email, "Value must be an email string")); | ||
} | ||
} | ||
|
||
struct ValidateMinimum(T) { | ||
T minimum; | ||
|
||
Nullable!ValidationError getError(T value, string path) { | ||
if (value.to!T >= this.minimum) { | ||
return Nullable!ValidationError.init; | ||
} | ||
|
||
return Nullable!ValidationError(ValidationError(path, ValidationErrorTypes.minimum, | ||
"Value cannot be less than " ~ this.minimum.to!string, | ||
["minimum": this.minimum.to!double])); | ||
} | ||
} | ||
|
||
struct ValidateMaximum(T) { | ||
T maximum; | ||
|
||
Nullable!ValidationError getError(T value, string path) { | ||
if (value.to!T <= this.maximum) { | ||
return Nullable!ValidationError.init; | ||
} | ||
|
||
return Nullable!ValidationError(ValidationError(path, ValidationErrorTypes.maximum, | ||
"Value cannot be greater isBuiltinTypethan " ~ this.maximum.to!string, | ||
["maximum": this.maximum.to!double])); | ||
} | ||
} | ||
|
||
struct ValidateMinimumLength { | ||
uint minimumLength; | ||
|
||
Nullable!ValidationError getError(string value, string path) { | ||
if (value.length >= this.minimumLength) { | ||
return Nullable!ValidationError.init; | ||
} | ||
|
||
return Nullable!ValidationError(ValidationError(path, ValidationErrorTypes.minimumLength, | ||
"Value cannot be shorter than " ~ this.minimumLength.to!string, | ||
["minimumLength": this.minimumLength.to!double])); | ||
} | ||
} | ||
|
||
struct ValidateMaximumLength { | ||
uint maximumLength; | ||
|
||
Nullable!ValidationError getError(string value, string path) { | ||
if (value.length <= this.maximumLength) { | ||
return Nullable!ValidationError.init; | ||
} | ||
|
||
return Nullable!ValidationError(ValidationError(path, ValidationErrorTypes.maximumLength, | ||
"Value cannot be longer than " ~ this.maximumLength.to!string, | ||
["maximumLength": this.maximumLength.to!double])); | ||
} | ||
} | ||
|
||
enum ValidationErrorTypes { | ||
type = "type", | ||
required = "required", | ||
email = "email", | ||
minimum = "minimum", | ||
maximum = "maximum", | ||
minimumLength = "minimumLength", | ||
maximumLength = "maximumLength" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
module dutils.validation.email; | ||
|
||
import std.regex : ctRegex, replace; | ||
|
||
bool isValidEmail(string email) { | ||
import std.typecons : No; | ||
import std.net.isemail : isEmail, EmailStatusCode; | ||
|
||
const result = isEmail(extractEmail(email), No.checkDns, EmailStatusCode.none); | ||
return result.statusCode == EmailStatusCode.valid; | ||
} | ||
|
||
const extractEmailPattern = ctRegex!r"^(.*?<\s*)?([^@]+@[^>]+).*$"; | ||
|
||
string extractEmail(string email) { | ||
return replace(email, extractEmailPattern, "$2"); | ||
} | ||
|
||
/** | ||
* extractEmail - Don't modify string without email | ||
*/ | ||
unittest { | ||
assert(extractEmail("this is not an email<noat>") == "this is not an email<noat>"); | ||
} | ||
|
||
/** | ||
* extractEmail - Don't modify string with only email | ||
*/ | ||
unittest { | ||
assert(extractEmail("anna.andersson@example.com") == "anna.andersson@example.com"); | ||
} | ||
|
||
/** | ||
* extractEmail - Extract email from string | ||
*/ | ||
unittest { | ||
assert(extractEmail( | ||
"\"Anna Andersson\" <anna.andersson@example.com>") == "anna.andersson@example.com"); | ||
} | ||
|
||
/** | ||
* isValidEmail - Valid email should return true | ||
*/ | ||
unittest { | ||
assert(isValidEmail("\"Anna Andersson\" <anna.andersson@example.com>")); | ||
} | ||
|
||
/** | ||
* isValidEmail - Invalid email should return false | ||
*/ | ||
unittest { | ||
assert(!isValidEmail("\"Anna Andersson\" <anna.anderssonexample.com>")); | ||
assert(!isValidEmail("Anna Andersson")); | ||
} |
Oops, something went wrong.