1 module dud.pkgdescription.duplicate; 2 3 import std.array : empty; 4 import std.algorithm.iteration : each; 5 import std.traits : FieldNameTuple; 6 import std.typecons : nullable; 7 import std.format : format; 8 9 import dud.semver.semver; 10 import dud.semver.versionrange; 11 import dud.pkgdescription; 12 13 @safe pure: 14 15 PackageDescription dup(const ref PackageDescription pkg) { 16 PackageDescription ret; 17 18 static foreach(mem; FieldNameTuple!(PackageDescription)) {{ 19 alias MemType = typeof(__traits(getMember, PackageDescription, mem)); 20 static if(is(MemType == string) 21 || is(MemType == SemVer) 22 || is(MemType == Path) 23 || is(MemType == UnprocessedPath) 24 || is(MemType == Paths) 25 || is(MemType == BuildOptions) 26 || is(MemType == Dependency[]) 27 || is(MemType == Platform[][]) 28 || is(MemType == SubPackage[]) 29 || is(MemType == BuildType[string]) 30 || is(MemType == ToolchainRequirement[Toolchain]) 31 || is(MemType == SubConfigs) 32 || is(MemType == BuildRequirements) 33 || is(MemType == PackageDescription[string]) 34 || is(MemType == String) 35 || is(MemType == Strings) 36 || is(MemType == string[])) 37 { 38 __traits(getMember, ret, mem) = __traits(getMember, pkg, mem).dup(); 39 } else static if(is(MemType == TargetType) 40 || is(MemType == string) 41 ) 42 { 43 __traits(getMember, ret, mem) = __traits(getMember, pkg, mem); 44 } else { 45 static assert(false, format( 46 "Type '%s' of member '%s' is not handled in dup", 47 MemType.stringof, mem)); 48 } 49 }} 50 51 return ret; 52 } 53 54 VersionRange dup(const ref VersionRange old) { 55 return old.dup(); 56 } 57 58 unittest { 59 import dud.pkgdescription.compare; 60 import dud.semver.versionrange; 61 auto old = parseVersionRange(">=1.15.0"); 62 assert(!old.isNull()); 63 64 VersionRange d = dup(old.get()); 65 assert(areEqual(old.get(), d)); 66 } 67 68 // 69 // ToolchainRequirement 70 // 71 72 ToolchainRequirement dup(const ref ToolchainRequirement old) pure { 73 ToolchainRequirement ret; 74 ret.no = old.no; 75 ret.version_ = old.version_.dup(); 76 return ret; 77 } 78 79 ToolchainRequirement[Toolchain] dup( 80 ref const(ToolchainRequirement[Toolchain]) old) 81 { 82 ToolchainRequirement[Toolchain] ret; 83 old.byKeyValue().each!(it => ret[it.key] = it.value.dup()); 84 return ret; 85 } 86 87 // 88 // TargetType 89 // 90 91 TargetType dup(const(TargetType) old) { 92 TargetType ret = old; 93 return ret; 94 } 95 96 // 97 // SemVer 98 // 99 100 SemVer dup(ref const(SemVer) old) { 101 return old.dup(); 102 } 103 104 SemVer[] dup(const(SemVer[]) old) { 105 SemVer[] ret; 106 old.each!(it => ret ~= it.dup()); 107 return ret; 108 } 109 110 // 111 // BuildOption 112 // 113 114 BuildOption[] dup(const(BuildOption[]) old) { 115 BuildOption[] ret; 116 old.each!(it => ret ~= it); 117 return ret; 118 } 119 120 BuildOptions dup(ref const(BuildOptions) old) { 121 BuildOptions ret; 122 ret.unspecifiedPlatform = old.unspecifiedPlatform.dup(); 123 foreach(key, value; old.platforms) { 124 ret.platforms[key] = value.dup(); 125 } 126 return ret; 127 } 128 129 // 130 // SubConfig 131 // 132 133 SubConfigs dup(ref const(SubConfigs) old) { 134 SubConfigs ret; 135 old.unspecifiedPlatform 136 .byKeyValue 137 .each!(it => ret.unspecifiedPlatform[it.key] = it.value); 138 139 foreach(key, value; old.configs) { 140 string[string] tmp; 141 foreach(key2, value2; value) { 142 tmp[key2] = value2; 143 } 144 ret.configs[key] = tmp; 145 } 146 return ret; 147 } 148 149 Platform[] dup(const(Platform[]) old) { 150 Platform[] ret; 151 old.each!(it => ret ~= it); 152 return ret; 153 } 154 155 Platform[][] dup(const(Platform[][]) old) { 156 Platform[][] ret; 157 old.each!(it => ret ~= it.dup); 158 return ret; 159 } 160 161 BuildType dup(const(BuildType) old) { 162 BuildType ret; 163 ret.pkg = old.pkg.dup(); 164 ret.name = old.name; 165 return ret; 166 } 167 168 BuildType[string] dup(const(BuildType[string]) old) { 169 BuildType[string] ret; 170 old.byKeyValue().each!(it => ret[it.key] = it.value.dup()); 171 return ret; 172 } 173 174 BuildRequirement[] dup(const(BuildRequirement[]) old) { 175 BuildRequirement[] ret; 176 old.each!(it => ret ~= it); 177 return ret; 178 } 179 180 BuildRequirementPlatform dup(const(BuildRequirementPlatform) old) { 181 return BuildRequirementPlatform( 182 old.requirements.dup(), 183 old.platforms.dup()); 184 } 185 186 BuildRequirements dup(const(BuildRequirements) old) { 187 BuildRequirements ret; 188 old.platforms.each!(it => ret.platforms ~= it.dup()); 189 return ret; 190 } 191 192 PackageDescription[string] dup(const(PackageDescription[string]) old) { 193 PackageDescription[string] ret; 194 old.byKeyValue().each!(it => ret[it.key] = it.value.dup()); 195 return ret; 196 } 197 198 SubPackage dup(ref const(SubPackage) old) { 199 SubPackage ret; 200 ret.path = old.path.dup(); 201 if(!old.inlinePkg.isNull()) { 202 ret.inlinePkg = nullable(old.inlinePkg.get().dup()); 203 } 204 return ret; 205 } 206 207 SubPackage[] dup(const(SubPackage[]) old) { 208 SubPackage[] ret; 209 old.each!(it => ret ~= it.dup()); 210 return ret; 211 } 212 213 // 214 // Dependency 215 // 216 217 Dependency dup(ref const(Dependency) old) { 218 Dependency ret; 219 ret.name = old.name; 220 ret.platforms = old.platforms.dup(); 221 ret.path = old.path.dup(); 222 if(!old.default_.isNull()) { 223 const bool o = old.default_.get(); 224 ret.default_ = o; 225 } 226 227 if(!old.optional.isNull()) { 228 const bool o = old.optional.get(); 229 ret.optional = o; 230 } 231 232 if(!old.version_.isNull()) { 233 VersionRange o = old.version_.get().dup; 234 ret.version_ = o; 235 } 236 return ret; 237 } 238 239 Dependency[] dup(const(Dependency[]) old) { 240 Dependency[] ret; 241 old.each!(it => ret ~= it.dup()); 242 return ret; 243 } 244 245 // 246 // String 247 // 248 249 StringsPlatform dup(ref const(StringsPlatform) old) { 250 StringsPlatform ret; 251 ret.strs = old.strs.dup(); 252 ret.platforms = old.platforms.dup(); 253 return ret; 254 } 255 256 Strings dup(ref const(Strings) old) { 257 Strings ret; 258 old.platforms.each!(p => ret.platforms ~= p.dup()); 259 return ret; 260 } 261 262 // 263 // String 264 // 265 266 StringPlatform dup(ref const(StringPlatform) old) { 267 StringPlatform ret; 268 ret.str = old.str.dup(); 269 ret.platforms = old.platforms.dup(); 270 return ret; 271 } 272 273 String dup(ref const(String) old) { 274 String ret; 275 old.platforms.each!(p => ret.platforms ~= p.dup()); 276 return ret; 277 } 278 279 // 280 // Paths 281 // 282 283 Paths dup(ref const(Paths) old) { 284 Paths ret; 285 old.platforms.each!(p => ret.platforms ~= p.dup()); 286 return ret; 287 } 288 289 // 290 // Path 291 // 292 293 PathPlatform dup(ref const(PathPlatform) old) { 294 PathPlatform ret; 295 ret.path = UnprocessedPath(old.path.path); 296 ret.platforms = old.platforms.dup(); 297 return ret; 298 } 299 300 PathPlatform[] dup(const(PathPlatform[]) old) { 301 PathPlatform[] ret; 302 old.each!(it => ret ~= it.dup()); 303 return ret; 304 } 305 306 UnprocessedPath dup(ref const(UnprocessedPath) old) { 307 return UnprocessedPath(old.path.dup()); 308 } 309 310 PathsPlatform dup(ref const(PathsPlatform) old) { 311 PathsPlatform ret; 312 old.paths.each!(it => ret.paths ~= it.dup()); 313 ret.platforms = old.platforms.dup(); 314 return ret; 315 } 316 317 PathsPlatform[] dup(const(PathsPlatform[]) old) { 318 PathsPlatform[] ret; 319 old.each!(it => ret ~= it.dup()); 320 return ret; 321 } 322 323 Path dup(ref const(Path) old) { 324 Path ret; 325 old.platforms.each!(p => ret.platforms ~= p.dup()); 326 return ret; 327 } 328 329 // 330 // string 331 // 332 333 string dup(const(string) old) { 334 return old; 335 } 336 337 string[] dup(const(string[]) old) { 338 string[] ret; 339 old.each!(it => ret ~= it); 340 return ret; 341 } 342 343 string[string] dup(const(string[string]) old) { 344 string[string] ret; 345 old.byKeyValue.each!(kv => ret[kv.key.dup()] = kv.value.dup()); 346 return ret; 347 }