1 module toml_foolery.encode.types.integer; 2 3 import std.traits : isIntegral; 4 import std.uni : isNumber; 5 6 import toml_foolery.encode; 7 8 9 package(toml_foolery.encode) enum bool makesTomlInteger(T) = ( 10 isIntegral!T && !(is(T == enum)) 11 ); 12 13 14 /// Serializes integral types into TOML Integer values. 15 /// Throws: 16 /// TomlEncodingException when value is out of range of valid TOML Integers 17 /// (can only happen when T is `ulong`). 18 package(toml_foolery.encode) void tomlifyValueImpl(T)( 19 const T value, 20 ref Appender!string buffer, 21 immutable string[] parentTables 22 ) 23 if (makesTomlInteger!T) 24 { 25 static if (is(T == ulong)) 26 { 27 if (value > long.max.to!ulong) 28 { 29 throw new TomlEncodingException( 30 "ulong value is out of TOML integer range (-2^63, 2^63 - 1): " ~ value.to!string 31 ); 32 } 33 } 34 35 string valueStr = value.to!string; 36 if ( 37 (valueStr.length >= 5 && valueStr[0].isNumber) || 38 (valueStr.length >= 6) 39 ) 40 { 41 valueStr = "%,?d".format('_', value); 42 } 43 else 44 { 45 valueStr = "%d".format(value); 46 } 47 48 buffer.put(valueStr); 49 } 50 51 52 @("Encode `byte` fields") 53 unittest 54 { 55 byte b1; 56 expect(_tomlifyValue(b1)).toEqual(`0`); 57 58 byte b2 = byte.max; 59 expect(_tomlifyValue(b2)).toEqual(`127`); 60 61 byte b3 = byte.min; 62 expect(_tomlifyValue(b3)).toEqual(`-128`); 63 } 64 65 @("Encode `ubyte` fields") 66 unittest 67 { 68 ubyte ub1; 69 expect(_tomlifyValue(ub1)).toEqual(`0`); 70 71 ubyte ub2 = 127; 72 expect(_tomlifyValue(ub2)).toEqual(`127`); 73 74 ubyte ub3 = ubyte.max; 75 expect(_tomlifyValue(ub3)).toEqual(`255`); 76 } 77 78 @("Encode `short` fields") 79 unittest 80 { 81 short s1; 82 expect(_tomlifyValue(s1)).toEqual(`0`); 83 84 short s2 = short.max; 85 expect(_tomlifyValue(s2)).toEqual(`32_767`); 86 87 short s3 = short.min; 88 expect(_tomlifyValue(s3)).toEqual(`-32_768`); 89 } 90 91 @("Encode `ushort` fields") 92 unittest 93 { 94 ushort us1; 95 expect(_tomlifyValue(us1)).toEqual(`0`); 96 97 ushort us2 = 32_768; 98 expect(_tomlifyValue(us2)).toEqual(`32_768`); 99 100 ushort us3 = ushort.max; 101 expect(_tomlifyValue(us3)).toEqual(`65_535`); 102 } 103 104 @("Encode `int` fields") 105 unittest 106 { 107 int i1; 108 expect(_tomlifyValue(i1)).toEqual(`0`); 109 110 int i2 = int.min; 111 expect(_tomlifyValue(i2)).toEqual(`-2_147_483_648`); 112 113 int i3 = int.max; 114 expect(_tomlifyValue(i3)).toEqual(`2_147_483_647`); 115 } 116 117 @("Encode `uint` fields") 118 unittest 119 { 120 uint ui1 = uint(0); 121 expect(_tomlifyValue(ui1)).toEqual(`0`); 122 123 uint ui2 = uint(2_147_483_648); 124 expect(_tomlifyValue(ui2)).toEqual(`2_147_483_648`); 125 126 uint ui3 = uint(uint.max); 127 expect(_tomlifyValue(ui3)).toEqual(`4_294_967_295`); 128 } 129 130 @("Encode `long` fields") 131 unittest 132 { 133 long l1; 134 expect(_tomlifyValue(l1)).toEqual(`0`); 135 136 long l2 = long.min; 137 expect(_tomlifyValue(l2)).toEqual(`-9_223_372_036_854_775_808`); 138 139 long l3 = long.max; 140 expect(_tomlifyValue(l3)).toEqual(`9_223_372_036_854_775_807`); 141 } 142 143 @("Encode `ulong` fields") 144 unittest 145 { 146 ulong ul1; 147 expect(_tomlifyValue(ul1)).toEqual(`0`); 148 149 ulong ul2 = long.max.to!ulong; 150 expect(_tomlifyValue(ul2)).toEqual(`9_223_372_036_854_775_807`); 151 152 ulong ul3 = long.max.to!ulong + 1; 153 expect({ _tomlifyValue(ul3); }).toThrow!TomlEncodingException; 154 155 ulong ul4 = ulong.max; 156 expect({ _tomlifyValue(ul4); }).toThrow!TomlEncodingException; 157 } 158 159 @("Separators should not be added to 4-digit negative numbers") 160 unittest 161 { 162 int n = -1234; 163 expect(_tomlifyValue(n)).toEqual(`-1234`); 164 }