github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/transform/startf/entry_reader.go (about)

     1  package startf
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  
     7  	"github.com/qri-io/dataset"
     8  	"github.com/qri-io/dataset/dsio"
     9  	"github.com/qri-io/starlib/util"
    10  	"go.starlark.net/starlark"
    11  )
    12  
    13  // EntryReader implements the dsio.EntryReader interface for starlark.Iterable's
    14  type EntryReader struct {
    15  	i    int
    16  	st   *dataset.Structure
    17  	iter starlark.Iterator
    18  	data starlark.Value
    19  }
    20  
    21  // NewEntryReader creates a new Entry Reader
    22  func NewEntryReader(st *dataset.Structure, iter starlark.Iterable) *EntryReader {
    23  	return &EntryReader{
    24  		st:   st,
    25  		data: iter.(starlark.Value),
    26  		iter: iter.Iterate(),
    27  	}
    28  }
    29  
    30  // Structure gives this reader's structure
    31  func (r *EntryReader) Structure() *dataset.Structure {
    32  	return r.st
    33  }
    34  
    35  // ReadEntry reads one entry from the reader
    36  func (r *EntryReader) ReadEntry() (e dsio.Entry, err error) {
    37  	// Read next element (key for object, value for array).
    38  	var next starlark.Value
    39  	if !r.iter.Next(&next) {
    40  		r.iter.Done()
    41  		return e, io.EOF
    42  	}
    43  
    44  	// Handle array entry.
    45  	tlt, err := dsio.GetTopLevelType(r.st)
    46  	if err != nil {
    47  		return
    48  	}
    49  	if tlt == "array" {
    50  		e.Index = r.i
    51  		r.i++
    52  		e.Value, err = util.Unmarshal(next)
    53  		if err != nil {
    54  			fmt.Printf("reading error: %s\n", err.Error())
    55  		}
    56  		return
    57  	}
    58  
    59  	// Handle object entry. Assume key is a string.
    60  	var ok bool
    61  	e.Key, ok = starlark.AsString(next)
    62  	if !ok {
    63  		fmt.Printf("key error: %s\n", next)
    64  	}
    65  	// Lookup the corresponding value for the key.
    66  	dict := r.data.(*starlark.Dict)
    67  	value, ok, err := dict.Get(next)
    68  	if err != nil {
    69  		fmt.Printf("reading error: %s\n", err.Error())
    70  	}
    71  	e.Value, err = util.Unmarshal(value)
    72  	if err != nil {
    73  		fmt.Printf("reading error: %s\n", err.Error())
    74  	}
    75  	return
    76  }
    77  
    78  // Close finalizes the reader
    79  func (r *EntryReader) Close() error {
    80  	// TODO (b5): consume & close iterator
    81  	return nil
    82  }