1 module model;
2 
3 version (unittest) import unit_threaded;
4 
5 struct Dependency
6 {
7     FullyQualifiedName client;
8 
9     FullyQualifiedName supplier;
10 
11     this(string client, string supplier)
12     {
13         this(FullyQualifiedName(client), FullyQualifiedName(supplier));
14     }
15 
16     this(FullyQualifiedName client, FullyQualifiedName supplier) @nogc nothrow
17     {
18         this.client = client;
19         this.supplier = supplier;
20     }
21 
22     int opCmp(ref const Dependency that) const @nogc nothrow pure @safe
23     {
24         import std.algorithm : cmp;
25 
26         int result = cmp(this.client.names, that.client.names);
27 
28         if (result == 0)
29         {
30             result = cmp(this.supplier.names, that.supplier.names);
31         }
32         return result;
33     }
34 }
35 
36 struct FullyQualifiedName
37 {
38     string[] names;
39 
40     this(string name)
41     {
42         import std.string : split;
43 
44         this(name.split('.'));
45     }
46 
47     this(string[] names) nothrow
48     {
49         this.names = names.dup;
50     }
51 
52     string toString() const pure @safe
53     {
54         import std.string : join;
55 
56         return this.names.join('.');
57     }
58 }
59 
60 string packages(FullyQualifiedName fullyQualifiedName) pure @safe
61 {
62     import std.algorithm : splitter;
63     import std.array : join;
64     import std.range : dropBackOne;
65 
66     return fullyQualifiedName.names
67         .dropBackOne
68         .join('.');
69 }
70 
71 @("split packages from a fully-qualified module name")
72 unittest
73 {
74     packages(FullyQualifiedName("bar.baz.foo")).should.be == "bar.baz";
75     packages(FullyQualifiedName("foo")).shouldBeEmpty;
76 }