1 module dud.resolve.versionconfigurationtoolchain; 2 3 import std.algorithm.iteration : map; 4 import std.array : array, empty; 5 import std.stdio; 6 import std.exception : enforce; 7 import std.array : empty; 8 import std.format : format; 9 import dud.semver.semver; 10 import dud.semver.parse; 11 import dud.semver.checks : allowsAll, allowsAny; 12 import dud.semver.versionrange; 13 import dud.semver.versionunion; 14 static import dud.semver.setoperation; 15 import dud.resolve.confs : Confs; 16 import dud.resolve.positive; 17 import dud.resolve.toolchain; 18 19 @safe pure: 20 21 /** The algebraic datatype that stores a version range and a configuration 22 */ 23 struct VersionConfigurationToolchain { 24 @safe pure: 25 VersionUnion ver; 26 Confs conf; 27 ToolchainVersionUnion[] toolchains; 28 } 29 30 VersionConfigurationToolchain dup(const(VersionConfigurationToolchain) old) { 31 return VersionConfigurationToolchain(old.ver.dup(), old.conf.dup() 32 , old.toolchains.map!(it => dud.resolve.toolchain.dup(it)).array); 33 } 34 35 VersionConfigurationToolchain invert(const(VersionConfigurationToolchain) conf) { 36 static import dud.resolve.confs; 37 return VersionConfigurationToolchain( 38 dud.semver.setoperation.invert(conf.ver) 39 , conf.conf.invert()); 40 } 41 42 bool allowsAny(const(VersionConfigurationToolchain) a, const(VersionConfigurationToolchain) b) { 43 static import dud.resolve.confs; 44 static import dud.semver.checks; 45 return dud.semver.checks.allowsAny(a.ver, b.ver) 46 && dud.resolve.confs.allowsAny(a.conf, b.conf) 47 && dud.resolve.toolchain.allowsAny(a.toolchains, b.toolchains); 48 } 49 50 bool allowsAll(const(VersionConfigurationToolchain) a, const(VersionConfigurationToolchain) b) { 51 static import dud.resolve.confs; 52 static import dud.semver.checks; 53 return dud.semver.checks.allowsAll(a.ver, b.ver) 54 && dud.resolve.confs.allowsAll(a.conf, b.conf) 55 && dud.resolve.toolchain.allowsAll(a.toolchains, b.toolchains); 56 } 57 58 VersionConfigurationToolchain intersectionOf(const(VersionConfigurationToolchain) a, 59 const(VersionConfigurationToolchain) b) 60 { 61 static import dud.resolve.confs; 62 static import dud.semver.setoperation; 63 return VersionConfigurationToolchain( 64 dud.semver.setoperation.intersectionOf(a.ver, b.ver) 65 , dud.resolve.confs.intersectionOf(a.conf, b.conf) 66 , dud.resolve.toolchain.intersectionOf(a.toolchains, b.toolchains)); 67 } 68 69 /** Return if a is a subset of b, or if a and b are disjoint, or 70 if a and b overlap 71 */ 72 SetRelation relation(const(VersionConfigurationToolchain) a, 73 const(VersionConfigurationToolchain) b) pure 74 { 75 static import dud.resolve.confs; 76 const SetRelation ver = allowsAll(b.ver, a.ver) 77 ? SetRelation.subset 78 : allowsAny(b.ver, a.ver) 79 ? SetRelation.overlapping 80 : SetRelation.disjoint; 81 82 const SetRelation conf = dud.resolve.confs.relation(a.conf, b.conf); 83 const SetRelation tc = dud.resolve.toolchain.relation(a.toolchains, 84 b.toolchains); 85 debug writefln("ver %s, conf %s, tc %s", ver, conf, tc); 86 87 //debug writefln("ver %s, conf %s", ver, conf); 88 if(ver == SetRelation.disjoint || conf == SetRelation.disjoint) { 89 return SetRelation.disjoint; 90 } 91 92 if(ver == SetRelation.overlapping || conf == SetRelation.overlapping) { 93 return SetRelation.overlapping; 94 } 95 96 assert(ver == SetRelation.subset && conf == SetRelation.subset, 97 format("a: %s, b: %s", a, b)); 98 return SetRelation.subset; 99 }