예제 #1
0
        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));
        }
예제 #2
0
파일: Union.cs 프로젝트: bryanedds/Sigma
        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));
        }