1 module dcorelib.valueobjects.constrainedstring;
2 
3 import std..string;
4 import std.exception;
5 
6 /**
7 Extend this class to make a read-only string that enforces a maximum length, and 
8 optionally whether a value must be provided.
9 **/
10 abstract class ConstrainedString
11 {
12     protected string value;
13     private string identifier;
14 
15     this(string newValue, in uint maxLength, bool valueRequired, string identifier) @safe
16     {
17         enforce(identifier != "", "Identifer for constrained string may not be empty");
18         
19         if (valueRequired && newValue.length == 0) {
20             throw new Exception(format("%s must have a value", identifier));
21         }
22         
23         if (newValue.length > maxLength) {
24             throw new Exception(
25                 format("%s must not have a length that is greater than %d characters", identifier, maxLength)
26             );
27         }
28 
29         this.identifier = identifier;
30         this.value = newValue;
31     }
32 
33     override public string toString() @safe
34     {
35         return this.value;
36     }
37 
38     public bool empty() @safe
39     {
40         return this.value.length == 0;
41     }
42 
43     public bool notEmpty() @safe
44     {
45         return this.value.length > 0;
46     }
47 
48     public string getIdentifier() @safe {
49         return this.identifier;
50     }
51 }
52 
53 unittest {
54     class VarChar10Required : ConstrainedString
55     {
56         this(string newValue, string identifier)
57         {
58             super(newValue, 10, true, identifier);
59         }
60     }
61 
62     class VarChar10NotRequired : ConstrainedString
63     {
64         this(string newValue, string identifer)
65         {
66             super(newValue, 10, false, identifer);
67         }
68     }
69 
70     /********************** UNIT TESTS THAT SHOULD FAIL ********************/
71     try {
72         auto name = new VarChar10Required("", "name");
73         assert(false, "Was able to create an required constrained string from a blank value");
74     } catch(Exception e) {
75 
76     }  
77 
78     try {
79         auto name = new VarChar10Required("Name Long!!", "name");
80         assert(false, "Was able to create a constrained string that is too long");
81     } catch(Exception e) {
82 
83     }
84 
85     /********************** UNIT TESTS THAT SHOULD PASS ********************/
86     auto name = new VarChar10Required("Bob Smith", "name");
87     assert(name.toString() == "Bob Smith");
88     assert(name.notEmpty());
89     assert(!name.empty());
90     assert(name.getIdentifier() == "name");
91 
92     auto blank = new VarChar10NotRequired("", "blank");
93     assert(blank.toString() == "");
94     assert(blank.empty());
95     assert(!blank.notEmpty());
96 }