public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == pointType) { return(value); } if (destinationType == typeof(string)) { return(ConvertTo(context, culture, value, typeof(Symbol)).ToString()); } if (destinationType == typeof(Symbol)) { var tagField = pointType.GetField(nameof(Union <bool, bool> .Tag)); var tag = (Enum)tagField.GetValue(value); var tagConverter = new SymbolicConverter(tagField.FieldType); var tagSymbol = new Symbol(tagConverter.ConvertToString(tag)); var dataField = pointType.GetField(nameof(Union <bool, bool> .Data)); var data = dataField.GetValue(value); var dataConverter = new SymbolicConverter(tag.TryGetAttributeOfType <UnionAttribute>().TryThen(attr => attr.Type) ?? dataField.FieldType); var dataSymbol = dataConverter.CanConvertTo(typeof(Symbol)) ? (Symbol)dataConverter.ConvertTo(data, typeof(Symbol)) : new Symbol(dataConverter.ConvertToString(data)); return(new Symbol(new List <Symbol>() { tagSymbol, dataSymbol })); } return(base.ConvertTo(context, culture, value, destinationType)); }
public RefConverter(Type pointType) { this.pointType = pointType; var valueProperty = pointType.GetProperty(nameof(Ref <bool> .Value)); valueConverter = new SymbolicConverter(valueProperty.PropertyType); }
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == pointType) { return(value); } if (destinationType == typeof(string)) { return(ConvertTo(context, culture, value, typeof(Symbol)).ToString()); } if (destinationType == typeof(Symbol)) { var recordType = pointType.GetConcreteTypes().Where(type => type.Name.StartsWith("Record`")).First(); var recordSize = recordType.GetGenericArguments().Length; var fieldSymbols = Enumerable.Range(0, recordSize).Select(index => { var fieldName = "Item" + (index + 1); var field = pointType.GetProperty(fieldName, BindingFlags.Public | BindingFlags.Instance); var fieldValue = field.GetValue(value, null); var fieldConverter = new SymbolicConverter(field.PropertyType); return(fieldConverter.CanConvertTo(typeof(Symbol)) ? (Symbol)fieldConverter.ConvertTo(fieldValue, typeof(Symbol)) : new Symbol(fieldConverter.ConvertToString(fieldValue))); }); return(new Symbol(fieldSymbols)); } return(base.ConvertTo(context, culture, value, destinationType)); }
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { var sourceType = value.GetType(); if (sourceType == pointType) { return(value); } if (sourceType == typeof(string)) { return(ConvertFrom(context, culture, Symbol.FromString((string)value))); } if (sourceType == typeof(Symbol)) { var symbol = (Symbol)value; try { var symbols = symbol.AsSymbols; var fields = symbols .Select((fieldSymbol, index) => { var fieldName = "Item" + (index + 1); var fieldProperty = pointType.GetProperty(fieldName, BindingFlags.Public | BindingFlags.Instance); var fieldConverter = new SymbolicConverter(fieldProperty.PropertyType); var fieldValue = fieldSymbol.Match( atom => fieldConverter.ConvertFromString(atom), number => fieldConverter.ConvertFromString(number), str => fieldConverter.ConvertFromString(SymbolParser.Explicitize(str)), _ => fieldSymbol, _ => fieldConverter.ConvertFrom(fieldSymbol)); return(fieldValue); }) .ToArray(); return(Activator.CreateInstance(pointType, fields)); } catch (Exception exn) { throw new ArgumentException($"Invalid form '{symbol}' for {value.GetType().FullName}. Required form is '[Value ...]'.", exn); } } return(base.ConvertFrom(context, culture, value)); }
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { var sourceType = value.GetType(); if (sourceType == pointType) { return(value); } if (sourceType == typeof(string)) { return(ConvertFrom(context, culture, Symbol.FromString((string)value))); } if (sourceType == typeof(Symbol)) { var symbol = (Symbol)value; try { var fields = symbol.AsSymbols; var tagField = pointType.GetField(nameof(Union <bool, bool> .Tag)); var tagConverter = new SymbolicConverter(tagField.FieldType); var tag = (Enum)tagConverter.ConvertFromString(fields[0].AsAtom); var dataField = pointType.GetField(nameof(Union <bool, bool> .Data)); var dataConverter = new SymbolicConverter(tag.TryGetAttributeOfType <UnionAttribute>().TryThen(attr => attr.Type) ?? dataField.FieldType); var data = fields[1].Match( atom => dataConverter.ConvertFromString(atom), number => dataConverter.ConvertFromString(number), str => dataConverter.ConvertFromString(SymbolParser.Explicitize(str)), _ => fields[1], _ => dataConverter.ConvertFrom(fields[1])); return(Activator.CreateInstance(pointType, new object[] { tag, data })); } catch (Exception exn) { throw new ArgumentException($"Invalid form '{symbol}' for {value.GetType().FullName}. Required form is '[Enum Value]'.", exn); } } return(base.ConvertFrom(context, culture, value)); }
public static T StringToValue <T>(string str) { var converter = new SymbolicConverter(typeof(T)); return((T)converter.ConvertFromString(str)); }
public static string ValueToString <T>(T value) { var converter = new SymbolicConverter(typeof(T)); return(converter.ConvertToString(value)); }
public static Symbol ValueToSymbol <T>(T value) { var converter = new SymbolicConverter(typeof(T)); return((Symbol)converter.ConvertTo(value, typeof(Symbol))); }