示例#1
0
        private static TreeDecoderDescriptor <TState, TNative, TKey, TElement> BindArray <TElement>(
            IReaderDefinition <TState, TNative, TKey, TEntity> parentDefinition, Func <TElement> constructor,
            Setter <TEntity, IEnumerable <TElement> > setter,
            TreeDecoderDescriptor <TState, TNative, TKey, TElement> elementDescriptor)
        {
            var elementDefinition = elementDescriptor.definition;

            parentDefinition.Callback = (IReader <TState, TNative, TKey> reader, TState state, ref TEntity entity) =>
            {
                var status = reader.ReadToArray(state, constructor, elementDefinition.Callback, out var browserMove);

                if (status != ReaderStatus.Succeeded)
                {
                    return(status);
                }

                using (var browser = new Browser <TElement>(browserMove))
                {
                    setter(ref entity, browser);

                    return(browser.Finish() ? ReaderStatus.Succeeded : ReaderStatus.Failed);
                }
            };

            return(elementDescriptor);
        }
示例#2
0
        public IDecoderDescriptor <TField> HasField <TField>(string name, Func <TField> constructor,
                                                             Setter <TEntity, TField> setter)
        {
            var fieldDefinition = this.definition.Create <TField>();
            var fieldDescriptor = new TreeDecoderDescriptor <TState, TNative, TKey, TField>(this.converter, fieldDefinition);

            return(TreeDecoderDescriptor <TState, TNative, TKey, TEntity> .BindField(this.definition, name, constructor,
                                                                                     setter, fieldDescriptor));
        }
示例#3
0
        public IDecoderDescriptor <TElement> HasElements <TElement>(Func <TElement> constructor,
                                                                    Setter <TEntity, IEnumerable <TElement> > setter)
        {
            var elementDefinition = this.definition.Create <TElement>();
            var elementDescriptor =
                new TreeDecoderDescriptor <TState, TNative, TKey, TElement>(this.converter, elementDefinition);

            return(TreeDecoderDescriptor <TState, TNative, TKey, TEntity> .BindArray(this.definition, constructor, setter,
                                                                                     elementDescriptor));
        }
示例#4
0
        public IDecoderDescriptor <TElement> HasElements <TElement>(Func <TElement> constructor,
                                                                    Setter <TEntity, IEnumerable <TElement> > setter, IDecoderDescriptor <TElement> descriptor)
        {
            if (!(descriptor is TreeDecoderDescriptor <TState, TNative, TKey, TElement> ancestor))
            {
                throw new ArgumentOutOfRangeException(nameof(descriptor), "incompatible descriptor type");
            }

            return(TreeDecoderDescriptor <TState, TNative, TKey, TEntity> .BindArray(this.definition, constructor, setter,
                                                                                     ancestor));
        }
示例#5
0
        public IDecoderDescriptor <TField> HasField <TField>(string name, Func <TField> constructor,
                                                             Setter <TEntity, TField> setter, IDecoderDescriptor <TField> descriptor)
        {
            if (!(descriptor is TreeDecoderDescriptor <TState, TNative, TKey, TField> ancestor))
            {
                throw new ArgumentOutOfRangeException(nameof(descriptor), "incompatible descriptor type");
            }

            return(TreeDecoderDescriptor <TState, TNative, TKey, TEntity> .BindField(this.definition, name, constructor,
                                                                                     setter, ancestor));
        }
示例#6
0
        public IDecoderDescriptor <TEntity> HasField(string name)
        {
            var fieldDefinition = this.definition.Create <TEntity>();
            var fieldDescriptor = new TreeDecoderDescriptor <TState, TNative, TKey, TEntity>(this.converter, fieldDefinition);
            var parentLookup    = this.definition.Lookup;
            var parentRoot      = parentLookup.Root;

            var success = parentLookup.ConnectTo(name,
                                                 (IReader <TState, TNative, TKey> reader, TState state, ref TEntity entity) =>
                                                 fieldDefinition.Callback(reader, state, ref entity));

            if (!success)
            {
                throw new InvalidOperationException($"field '{name}' was declared twice on same descriptor");
            }

            this.definition.Callback = (IReader <TState, TNative, TKey> reader, TState state, ref TEntity target) =>
                                       reader.ReadToObject(state, parentRoot, ref target);

            return(fieldDescriptor);
        }
示例#7
0
        private static TreeDecoderDescriptor <TState, TNative, TKey, TField> BindField <TField>(
            IReaderDefinition <TState, TNative, TKey, TEntity> parentDefinition, string name, Func <TField> constructor,
            Setter <TEntity, TField> setter, TreeDecoderDescriptor <TState, TNative, TKey, TField> fieldDescriptor)
        {
            var fieldDefinition = fieldDescriptor.definition;
            var parentLookup    = parentDefinition.Lookup;
            var parentRoot      = parentLookup.Root;

            var success = parentLookup.ConnectTo(name,
                                                 (IReader <TState, TNative, TKey> reader, TState state, ref TEntity entity) =>
            {
                var field = constructor();

                switch (fieldDefinition.Callback(reader, state, ref field))
                {
                case ReaderStatus.Failed:
                    return(ReaderStatus.Failed);

                case ReaderStatus.Succeeded:
                    setter(ref entity, field);

                    break;
                }

                return(ReaderStatus.Succeeded);
            });

            if (!success)
            {
                throw new InvalidOperationException($"field '{name}' was declared twice on same descriptor");
            }

            parentDefinition.Callback = (IReader <TState, TNative, TKey> reader, TState state, ref TEntity target) =>
                                        reader.ReadToObject(state, parentRoot, ref target);

            return(fieldDescriptor);
        }