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); }
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); }
public TreeDecoderDescriptor(IDecoderConverter <TNative> converter, IReaderDefinition <TState, TNative, TKey, TEntity> definition) { this.converter = converter; this.definition = definition; }