1 // traffic_3
  2 
  3 using System;
  4 using System.Collections;
  5 using System.Xml;
  6 using System.Xml.Serialization;
  7 
  8 public enum Color
  9 {
 10     whiteblackredblue
 11 }
 12 
 13 public string ColorStr(Color color)
 14 {
 15     switch (color)
 16     {
 17         case Color.white: return "white";
 18         case Color.black: return "black";
 19         case Color.red: return "red";
 20         case Color.blue: return "blue";
 21     }
 22     return "<unknown color>";
 23 }
 24 
 25 [xml]
 26 public abstract class Vehicle
 27 {
 28     public Vehicle()
 29     {
 30     }
 31     public virtual default ~Vehicle();
 32     public void SetOwner(Person* owner_)
 33     {
 34         owner = owner_;
 35     }
 36     public void SetModel(const string& model_)
 37     {
 38         model = model_;
 39     }
 40     public inline const string& Model() const
 41     {
 42         return model;
 43     }
 44     public void SetColor(Color color_)
 45     {
 46         color = color_;
 47     }
 48     public inline Color GetColor() const
 49     {
 50         return color;
 51     }
 52     public virtual void Print()
 53     {
 54         Console.Out() << ClassName() << "\n";
 55         if (!owner.IsNull())
 56         {
 57             Console.Out() << "owner: " << owner->Name() << "\n";
 58         }
 59         Console.Out() << "model: " << model << "\n";
 60         Console.Out() << "color: " << ColorStr(color) << "\n";
 61     }
 62     private string model;
 63     private Color color;
 64     private System.Xml.Serialization.XmlPtr<Person> owner;
 65 }
 66 
 67 [xml]
 68 public class Bicycle : Vehicle
 69 {
 70     public Bicycle()
 71     {
 72     }
 73     public inline int Price()
 74     {
 75         return price;
 76     }
 77     public void SetPrice(int price_)
 78     {
 79         price = price_;
 80     }
 81     public override void Print()
 82     {
 83         base->Print();
 84         Console.Out() << "price: " << price << "\n";
 85     }
 86     private int price;
 87 }
 88 
 89 [xml]
 90 public class Car : Vehicle
 91 {
 92     public Car()
 93     {
 94     }
 95     public void SetRegistrationNumber(const string& registrationNumber_)
 96     {
 97         registrationNumber = registrationNumber_;
 98     }
 99     public inline const string& RegistrationNumber() const
100     {
101         return registrationNumber;
102     }
103     public override void Print()
104     {
105         base->Print();
106         Console.Out() << "registrationNumber: " << registrationNumber << "\n";
107     }
108     private string registrationNumber;
109 }
110 
111 [xml]
112 public class Person
113 {
114     public Person()
115     {
116     }
117     public Person(const string& name_) : name(name_)
118     {
119     }
120     public inline const string& Name() const
121     {
122         return name;
123     }
124     public void AddVehicle(Vehicle* vehicle)
125     {
126         vehicle->SetOwner(this);
127         vehicles.Add(System.Xml.Serialization.XmlPtr<Vehicle>(vehicle));
128     }
129     public void Print()
130     {
131         Console.Out() << "Person" << "\n";
132         Console.Out() << "name: " << name << "\n";
133         Console.Out() << "vehicles:" << "\n";
134         for (const auto& vehicle : vehicles)
135         {
136             vehicle->Print();
137         }
138     }
139     private string name;
140     private List<System.Xml.Serialization.XmlPtr<Vehicle>> vehicles;
141 }
142 
143 [nodiscard]
144 Result<bool> Register()
145 {
146     auto result = Person.Register();
147     if (result.Error()) return result;
148     result = Bicycle.Register();
149     if (result.Error()) return result;
150     result = Car.Register();
151     if (result.Error()) return result;
152     return Result<bool>(true);
153 }
154 
155 int main()
156 {
157     auto registerResult = Register();
158     if (registerResult.Error())
159     {
160         Console.Error() << registerResult.GetErrorMessage() << "\n";
161         return 1;
162     }
163     System.Xml.Serialization.XmlBundle bundle;
164     Person* joe = new Person("Joe Coder");
165     bundle.Add(joe);
166     Bicycle* cooper = new Bicycle();
167     cooper->SetModel("Cooper");
168     cooper->SetColor(Color.blue);
169     cooper->SetPrice(1000);
170     joe->AddVehicle(cooper);
171     bundle.Add(cooper);
172     Car* porsche = new Car();
173     porsche->SetModel("Porsche");
174     porsche->SetColor(Color.red);
175     porsche->SetRegistrationNumber("ABC-123");
176     joe->AddVehicle(porsche);
177     bundle.Add(porsche);
178     Result<UniquePtr<System.Xml.Document>> xmlDocumentResult = bundle.ToXmlDocument();
179     if (xmlDocumentResult.Error())
180     {
181         Console.Error() << xmlDocumentResult.GetErrorMessage() << "\n";
182         return 1;
183     }
184     System.Xml.Document* document = xmlDocumentResult.Value().Get();
185     System.Text.CodeFormatter formatter(Console.Out());
186     formatter.SetIndentSize(1);
187     Result<bool> writeResult = document->Write(formatter);
188     if (writeResult.Error())
189     {
190         Console.Error() << writeResult.GetErrorMessage() << "\n";
191         return 1;
192     }
193     System.Xml.Serialization.XmlBundle readBundle;
194     System.Xml.Serialization.XmlSerializationContext ctx;
195     ctx.SetFlag(System.Xml.Serialization.XmlSerializationFlags.failOnNotFoundObjects);
196     Result<bool> fromXmlResult = readBundle.FromXml(*documentctx);
197     if (fromXmlResult.Error())
198     {
199         Console.Error() << fromXmlResult.GetErrorMessage() << "\n";
200         return 1;
201     }
202     if (readBundle.Count() != 3)
203     {
204         Console.Error() << "three objects expected" << "\n";
205         return 1;
206     }
207     System.Xml.Serialization.XmlSerializable* first = readBundle.Get(0);
208     if (first is Person*)
209     {
210         Person* person = cast<Person*>(first);
211         person->Print();
212     }
213     else
214     {
215         Console.Error() << "Person object expected" << "\n";
216     }
217     return 0;
218 }