1 /* 2 * Hunt - A data validation for DLang based on hunt library. 3 * 4 * Copyright (C) 2015-2019, HuntLabs 5 * 6 * Website: https://www.huntlabs.net 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 module hunt.validation.DeclDef; 12 13 import std.traits; 14 15 import hunt.validation.validators.AssertFalseValidator; 16 import hunt.validation.validators.AssertTrueValidator; 17 import hunt.validation.validators.EmailValidator; 18 import hunt.validation.validators.LengthValidator; 19 import hunt.validation.validators.MaxValidator; 20 import hunt.validation.validators.MinValidator; 21 import hunt.validation.validators.NotBlankValidator; 22 import hunt.validation.validators.NotEmptyValidator; 23 import hunt.validation.validators.PatternValidator; 24 import hunt.validation.validators.SizeValidator; 25 import hunt.validation.constraints.AssertFalse; 26 import hunt.validation.constraints.AssertTrue; 27 import hunt.validation.constraints.Email; 28 import hunt.validation.constraints.Max; 29 import hunt.validation.constraints.Min; 30 import hunt.validation.constraints.NotBlank; 31 import hunt.validation.constraints.NotEmpty; 32 import hunt.validation.constraints.Pattern; 33 import hunt.validation.constraints.Size; 34 import hunt.validation.constraints.Length; 35 import hunt.validation.constraints.Range; 36 37 38 mixin template MakeValid() 39 { 40 mixin(makeValidInit); 41 mixin(makeDoValid!(typeof(this))); 42 } 43 44 string makeValidInit() 45 { 46 string str = ` 47 private ConstraintValidatorContext _context; 48 public ConstraintValidatorContext valid(){ return doValid() ;} 49 `; 50 51 return str; 52 } 53 54 bool hasAnnotation(T, A)() { 55 bool res = false; 56 foreach(a; __traits(getAttributes, T)) { 57 static if (is(typeof(a) == A) || a.stringof == A.stringof) { 58 res = true; 59 break; 60 } 61 } 62 return res; 63 } 64 65 string makeDoValid(T)() 66 { 67 string str = ` 68 private ConstraintValidatorContext doValid() 69 { 70 if(_context is null) 71 _context = new DefaultConstraintValidatorContext(); 72 return doValid(_context); 73 } 74 75 public ConstraintValidatorContext doValid(ConstraintValidatorContext context) 76 {`; 77 foreach(memberName; __traits(derivedMembers, T)) { 78 static if (__traits(getProtection, __traits(getMember, T, memberName)) == "public") { 79 alias memType = typeof(__traits(getMember, T ,memberName)); 80 static if (!isFunction!(memType)) { 81 static if(hasUDA!(__traits(getMember, T ,memberName), Max)) 82 { 83 str ~=` { 84 MaxValidator validator = new MaxValidator();`; 85 static if((getUDAs!(__traits(getMember, T ,memberName), Max)[0]).stringof == Max.stringof) 86 { 87 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), Max)[0]).stringof~ `());`; 88 } 89 else 90 { 91 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), Max)[0]).stringof~ `);`; 92 } 93 str ~=` validator.setPropertyName(`~memberName.stringof~`); 94 validator.isValid(this.` ~ memberName ~ `,context); 95 }`; 96 } 97 static if(hasUDA!(__traits(getMember, T ,memberName), Min)) 98 { 99 str ~=` { 100 MinValidator validator = new MinValidator();`; 101 static if((getUDAs!(__traits(getMember, T ,memberName), Min)[0]).stringof == Min.stringof) 102 { 103 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), Min)[0]).stringof~ `());`; 104 } 105 else 106 { 107 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), Min)[0]).stringof~ `);`; 108 } 109 str ~=` validator.setPropertyName(`~memberName.stringof~`); 110 validator.isValid(this.` ~ memberName ~ `,context); 111 }`; 112 } 113 static if(hasUDA!(__traits(getMember, T ,memberName), AssertFalse)) 114 { 115 str ~=` { 116 AssertFalseValidator validator = new AssertFalseValidator();`; 117 static if((getUDAs!(__traits(getMember, T ,memberName), AssertFalse)[0]).stringof == AssertFalse.stringof) 118 { 119 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), AssertFalse)[0]).stringof~ `());`; 120 } 121 else 122 { 123 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), AssertFalse)[0]).stringof~ `);`; 124 } 125 str ~=` validator.setPropertyName(`~memberName.stringof~`); 126 validator.isValid(this.` ~ memberName ~ `,context); 127 }`; 128 } 129 static if(hasUDA!(__traits(getMember, T ,memberName), AssertTrue)) 130 { 131 str ~=` { 132 AssertTrueValidator validator = new AssertTrueValidator();`; 133 static if((getUDAs!(__traits(getMember, T ,memberName), AssertTrue)[0]).stringof == AssertTrue.stringof) 134 { 135 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), AssertTrue)[0]).stringof~ `());`; 136 } 137 else 138 { 139 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), AssertTrue)[0]).stringof~ `);`; 140 } 141 str ~=` validator.setPropertyName(`~memberName.stringof~`); 142 validator.isValid(this.` ~ memberName ~ `,context); 143 }`; 144 } 145 static if(hasUDA!(__traits(getMember, T ,memberName), Email)) 146 { 147 str ~=` { 148 EmailValidator validator = new EmailValidator();`; 149 static if((getUDAs!(__traits(getMember, T ,memberName), Email)[0]).stringof == Email.stringof) 150 { 151 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), Email)[0]).stringof~ `());`; 152 } 153 else 154 { 155 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), Email)[0]).stringof~ `);`; 156 } 157 str ~=` validator.setPropertyName(`~memberName.stringof~`); 158 validator.isValid(this.` ~ memberName ~ `,context); 159 }`; 160 } 161 static if(hasUDA!(__traits(getMember, T ,memberName), Length)) 162 { 163 str ~=` { 164 LengthValidator validator = new LengthValidator();`; 165 static if((getUDAs!(__traits(getMember, T ,memberName), Length)[0]).stringof == Length.stringof) 166 { 167 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), Length)[0]).stringof~ `());`; 168 } 169 else 170 { 171 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), Length)[0]).stringof~ `);`; 172 } 173 str ~=` validator.setPropertyName(`~memberName.stringof~`); 174 validator.isValid(this.` ~ memberName ~ `,context); 175 }`; 176 } 177 static if(hasUDA!(__traits(getMember, T ,memberName), NotBlank)) 178 { 179 str ~=` { 180 NotBlankValidator validator = new NotBlankValidator();`; 181 static if((getUDAs!(__traits(getMember, T ,memberName), NotBlank)[0]).stringof == NotBlank.stringof) 182 { 183 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), NotBlank)[0]).stringof~ `());`; 184 } 185 else 186 { 187 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), NotBlank)[0]).stringof~ `);`; 188 } 189 str ~=` validator.setPropertyName(`~memberName.stringof~`); 190 validator.isValid(this.` ~ memberName ~ `,context); 191 }`; 192 } 193 static if(hasUDA!(__traits(getMember, T ,memberName), NotEmpty)) 194 { 195 str ~=` { 196 auto validator = new NotEmptyValidator!`~memType.stringof~`();`; 197 static if((getUDAs!(__traits(getMember, T ,memberName), NotEmpty)[0]).stringof == NotEmpty.stringof) 198 { 199 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), NotEmpty)[0]).stringof~ `());`; 200 } 201 else 202 { 203 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), NotEmpty)[0]).stringof~ `);`; 204 } 205 str ~=` validator.setPropertyName(`~memberName.stringof~`); 206 validator.isValid(this.` ~ memberName ~ `,context); 207 }`; 208 } 209 static if(hasUDA!(__traits(getMember, T ,memberName), Pattern)) 210 { 211 str ~=` { 212 PatternValidator validator = new PatternValidator();`; 213 static if((getUDAs!(__traits(getMember, T ,memberName), Pattern)[0]).stringof == Pattern.stringof) 214 { 215 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), Pattern)[0]).stringof~ `());`; 216 } 217 else 218 { 219 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), Pattern)[0]).stringof~ `);`; 220 } 221 str ~=` validator.setPropertyName(`~memberName.stringof~`); 222 validator.isValid(this.` ~ memberName ~ `,context); 223 }`; 224 } 225 static if(hasUDA!(__traits(getMember, T ,memberName), Size)) 226 { 227 str ~=` { 228 auto validator = new SizeValidator!`~memType.stringof~`();`; 229 static if((getUDAs!(__traits(getMember, T ,memberName), Size)[0]).stringof == Size.stringof) 230 { 231 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), Size)[0]).stringof~ `());`; 232 } 233 else 234 { 235 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), Size)[0]).stringof~ `);`; 236 } 237 str ~=` validator.setPropertyName(`~memberName.stringof~`); 238 validator.isValid(this.` ~ memberName ~ `,context); 239 }`; 240 } 241 static if(hasUDA!(__traits(getMember, T ,memberName), Range)) 242 { 243 str ~=` { 244 RangeValidator validator = new RangeValidator();`; 245 static if((getUDAs!(__traits(getMember, T ,memberName), Range)[0]).stringof == Range.stringof) 246 { 247 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), Range)[0]).stringof~ `());`; 248 } 249 else 250 { 251 str ~=` validator.initialize(`~ (getUDAs!(__traits(getMember, T ,memberName), Range)[0]).stringof~ `);`; 252 } 253 str ~=` validator.setPropertyName(`~memberName.stringof~`); 254 validator.isValid(this.` ~ memberName ~ `,context); 255 }`; 256 } 257 } 258 } 259 } 260 str ~= " return context;"; 261 str ~=`}`; 262 return str; 263 }