fn f1() -> Result<(), E1> {...}
fn f2() -> Result<(), E2> {...}
fn f3() -> Result<(), E3> {...}
fn f4() -> Result<(), E4> {f1()?; f2()?;}
fn f5() -> Result<(), E5> {f1()?; f3()?;}
fn f6() -> Result<(), E6> {f4()?; f5()?;}
Now, how do you define E4, E5 and E6? The "correct" way is to use sum types, i.e., `enum E4 {E1(E1), E2(E2)}`, `enum E5 {E1(E1), E3(E3)}` and `enum E6 {E1(E1), E2(E2), E3(E3)}` with the appropriate From traits. The problem is that this involves a ton of boilerplate even with thiserror handling some stuff like the From traits. auto get_ids(std::span<const Widget> data)
{
auto pipeline = filter(&Widget::alive) | transform(&Widget::id);
auto sink = to<std::vector>();
return data | pipeline | sink;
} data FooResult = Number | Number
If you can't distinguish the two cases, then it means they're not an actual sum type, since e.g. the set size is |FooResult| = |Number| whereas a sum type should have 2*|Number|. ErrorA = FileNotFoundError | ParsingError
ErrorB = FileNotFoundError | PermissionError
ErrorC = ErrorA | ErrorB // Oops, trying to ad hoc sum FileNotFoundError twice
The tried and true solution in HM is to use generic types like Result<A,B>, where you separate the cases with labels Ok and Err. (T1, ..., Tn) Apply<T1, ..., Tn>((Func<P, T1>, ..., Func<P, Tn>) args)
This is not possible in C# because the language doesn't have variadic generics. Instead, I used runtime reflection and wrote something like this: object[] Apply(Func<P, object>[] args)
Although it worked, the downside is that the types T1, ..., Tn are no longer statically known, which means that the function's contract has to be written in comments and the caller has to check them manually. In contrast, C++ has variadic templates, which would allow the compiler to check the types automatically.
To my understanding, reverse engineering algorithms and interfaces is not a copyright violation since those cannot be copyrighted (i.e. fair use is not relevant). However, a WoW server also distributes e.g. quest texts, which most certainly are copyrightable, since the collective of all quests is comparable to a fantasy novel.
In backend terms (which isn't really relevant in court but helps illustrate the division), every WoW server is said to have a "core" that contains the gameplay logic (netcode, movement, hit rolls, object interactions, etc.) and a "world database" (item names and stats, NPC names and stats, quests, etc.). The core might be considered a collection of clean room reverse engineered algorithms, which aren't copyrightable. However, the world database is full of copyrighted material, and a server distributing that data to clients will violate Blizzard's copyrights. You could avoid this by deleting all of Blizzard's stuff from the world database and writing your own content, but it's not relevant here since Turtle WoW didn't do that.
Nonetheless, vbezhenar's point stands because there are open source server implementations that host both the core and the database on Github, see e.g. https://github.com/cmangos/mangos-tbc and https://github.com/cmangos/tbc-db.