namespace Vellum.UnitTests { public class Animal { public string Name; } public class AnimalConverter : SaveConverter { public override SaveNode Write(Animal value, SaveSession session) { SaveNode returnMe = SaveNode.NewTable(); returnMe.Entries["name"] = session.ToNode(value.Name, typeof(string)); return returnMe; } public override Animal Read(SaveNode node, SaveSession session) { return new Animal { Name = (string)session.FromNode(node.RequireEntry("name"), typeof(string)) }; } } public class Dog : Animal { public bool Barks; } public class DogConverter : SaveConverter { public override SaveNode Write(Dog value, SaveSession session) { SaveNode returnMe = SaveNode.NewTable(); returnMe.Entries["name"] = session.ToNode(value.Name, typeof(string)); returnMe.Entries["barks"] = session.ToNode(value.Barks, typeof(bool)); return returnMe; } public override Dog Read(SaveNode node, SaveSession session) { return new Dog { Name = (string)session.FromNode(node.RequireEntry("name"), typeof(string)), Barks = (bool)session.FromNode(node.RequireEntry("barks"), typeof(bool)), }; } } /// /// An animal whose converter writes text rather than a table. /// public class Fish : Animal { } public class FishConverter : SaveConverter { public override SaveNode Write(Fish value, SaveSession session) { return SaveNode.OfText(value.Name); } public override Fish Read(SaveNode node, SaveSession session) { return new Fish { Name = node.RequireText() }; } } /// /// A subtype of a converted type that nothing converts. /// #pragma warning disable VEL0010 public class Eel : Fish { } #pragma warning restore VEL0010 public class Tricky : Animal { } public class TrickyConverter : SaveConverter { public override SaveNode Write(Tricky value, SaveSession session) { SaveNode returnMe = SaveNode.NewTable(); returnMe.Entries[SaveConverters.TypeKey] = SaveNode.OfText("somewhere else"); return returnMe; } public override Tricky Read(SaveNode node, SaveSession session) { return new Tricky(); } } public class Sneaky : Animal { } public class SneakyConverter : SaveConverter { public override SaveNode Write(Sneaky value, SaveSession session) { SaveNode returnMe = SaveNode.NewTable(); returnMe.Entries[SaveConverters.ValueKey] = SaveNode.OfText("hidden"); return returnMe; } public override Sneaky Read(SaveNode node, SaveSession session) { return new Sneaky(); } } /// /// An animal that holds another animal, to drive the converters' depth limit through subtypes. /// public class Mole : Animal { public Animal Inner; public static Mole Chain(int count) { Mole returnMe = null; for (int i = 0; i < count; ++i) { returnMe = new Mole { Inner = returnMe }; } return returnMe; } } public class MoleConverter : SaveConverter { public override SaveNode Write(Mole value, SaveSession session) { SaveNode returnMe = SaveNode.NewTable(); returnMe.Entries["inner"] = session.ToNode(value.Inner, typeof(Animal)); return returnMe; } public override Mole Read(SaveNode node, SaveSession session) { return new Mole { Inner = (Animal)session.FromNode(node.RequireEntry("inner"), typeof(Animal)) }; } } /// /// A class that is equal to any other with the same Id. /// public class Stamp { public string Id; public override bool Equals(object obj) { var other = obj as Stamp; return other != null && other.Id == Id; } public override int GetHashCode() { return Id.GetHashCode(); } } public class StampConverter : SaveConverter { public override SaveNode Write(Stamp value, SaveSession session) { SaveNode returnMe = SaveNode.NewTable(); returnMe.Entries["id"] = session.ToNode(value.Id, typeof(string)); return returnMe; } public override Stamp Read(SaveNode node, SaveSession session) { return new Stamp { Id = (string)session.FromNode(node.RequireEntry("id"), typeof(string)) }; } } /// /// A class whose converter saves it as whatever the other one saves as. /// public class Echo { public Echo Other; } public class EchoConverter : SaveConverter { public override SaveNode Write(Echo value, SaveSession session) { return session.ToNode(value.Other, typeof(Echo)); } public override Echo Read(SaveNode node, SaveSession session) { return new Echo(); } } /// /// A class that can be its own twin, whose converter builds it without telling anyone. /// public class Desk { public Desk Twin; } public class DeskConverter : SaveConverter { public override SaveNode Write(Desk value, SaveSession session) { SaveNode returnMe = SaveNode.NewTable(); returnMe.Entries["twin"] = session.ToNode(value.Twin, typeof(Desk)); return returnMe; } public override Desk Read(SaveNode node, SaveSession session) { return new Desk { Twin = (Desk)session.FromNode(node.RequireEntry("twin"), typeof(Desk)) }; } } /// /// A class that can be its own twin, whose converter builds it first and hands it out before filling it in. /// public class Chair { public Chair Twin; } public class ChairConverter : SaveConverter { public override SaveNode Write(Chair value, SaveSession session) { SaveNode returnMe = SaveNode.NewTable(); returnMe.Entries["twin"] = session.ToNode(value.Twin, typeof(Chair)); return returnMe; } public override Chair Read(SaveNode node, SaveSession session) { var returnMe = new Chair(); session.Publish(node, returnMe); returnMe.Twin = (Chair)session.FromNode(node.RequireEntry("twin"), typeof(Chair)); return returnMe; } } public interface IPet { string Nickname { get; } } public struct Hamster : IPet { public string Nickname { get; set; } } public class HamsterConverter : SaveConverter { public override SaveNode Write(Hamster value, SaveSession session) { SaveNode returnMe = SaveNode.NewTable(); returnMe.Entries["nickname"] = session.ToNode(value.Nickname, typeof(string)); return returnMe; } public override Hamster Read(SaveNode node, SaveSession session) { return new Hamster { Nickname = (string)session.FromNode(node.RequireEntry("nickname"), typeof(string)), }; } } /// /// A pet that nothing converts. /// public class Stray : IPet { public string Nickname { get { return "stray"; } } } }