github.com/fraugster/parquet-go@v0.12.0/floor/interfaces/unmarshaller.go (about)

     1  package interfaces
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  )
     7  
     8  var (
     9  	// ErrFieldNotPresent indicate the field is not available in the result
    10  	ErrFieldNotPresent = errors.New("field is not present")
    11  )
    12  
    13  // Unmarshaller is the interface necessary for objects to
    14  // be unmarshalled.
    15  type Unmarshaller interface {
    16  	UnmarshalParquet(obj UnmarshalObject) error
    17  }
    18  
    19  // UnmarshalObject is the interface an Unmarshaller needs to unmarshal its data
    20  // from.
    21  type UnmarshalObject interface {
    22  	GetField(field string) UnmarshalElement
    23  
    24  	GetData() map[string]interface{}
    25  }
    26  
    27  // UnmarshalElement describes the interface to get the value of an element in an Unmarshaller
    28  // implementation.
    29  type UnmarshalElement interface {
    30  	Group() (UnmarshalObject, error)
    31  	Int32() (int32, error)
    32  	Int64() (int64, error)
    33  	Int96() ([12]byte, error)
    34  	Float32() (float32, error)
    35  	Float64() (float64, error)
    36  	Bool() (bool, error)
    37  	ByteArray() ([]byte, error)
    38  	List() (UnmarshalList, error)
    39  	Map() (UnmarshalMap, error)
    40  	Error() error
    41  }
    42  
    43  // UnmarshalList describes the interface to get the values of a list in an Unmarshaller
    44  // implementation.
    45  type UnmarshalList interface {
    46  	Next() bool
    47  	Value() (UnmarshalElement, error)
    48  }
    49  
    50  // UnmarshalMap describes the interface to get key-value pairs of a map in an Unmarshaller
    51  // implementation.
    52  type UnmarshalMap interface {
    53  	Next() bool
    54  	Key() (UnmarshalElement, error)
    55  	Value() (UnmarshalElement, error)
    56  }
    57  
    58  type unmarshalErr struct {
    59  }
    60  
    61  func (u unmarshalErr) Error() error {
    62  	return ErrFieldNotPresent
    63  }
    64  
    65  func (u unmarshalErr) Group() (UnmarshalObject, error) {
    66  	return nil, ErrFieldNotPresent
    67  }
    68  
    69  func (u unmarshalErr) Int32() (int32, error) {
    70  	return 0, ErrFieldNotPresent
    71  }
    72  
    73  func (u unmarshalErr) Int64() (int64, error) {
    74  	return 0, ErrFieldNotPresent
    75  }
    76  
    77  func (u unmarshalErr) Int96() ([12]byte, error) {
    78  	return [12]byte{}, ErrFieldNotPresent
    79  }
    80  
    81  func (u unmarshalErr) Float32() (float32, error) {
    82  	return 0, ErrFieldNotPresent
    83  }
    84  
    85  func (u unmarshalErr) Float64() (float64, error) {
    86  	return 0, ErrFieldNotPresent
    87  }
    88  
    89  func (u unmarshalErr) Bool() (bool, error) {
    90  	return false, ErrFieldNotPresent
    91  }
    92  
    93  func (u unmarshalErr) ByteArray() ([]byte, error) {
    94  	return nil, ErrFieldNotPresent
    95  }
    96  
    97  func (u unmarshalErr) List() (UnmarshalList, error) {
    98  	return nil, ErrFieldNotPresent
    99  }
   100  
   101  func (u unmarshalErr) Map() (UnmarshalMap, error) {
   102  	return nil, ErrFieldNotPresent
   103  }
   104  
   105  func (o *object) GetField(field string) UnmarshalElement {
   106  	fieldData, ok := o.data[field]
   107  	if !ok {
   108  		return &unmarshalErr{}
   109  	}
   110  
   111  	return &unmarshElem{data: fieldData}
   112  }
   113  
   114  type unmarshElem struct {
   115  	data interface{}
   116  }
   117  
   118  func (e *unmarshElem) Error() error {
   119  	return nil
   120  }
   121  
   122  func (e *unmarshElem) Group() (UnmarshalObject, error) {
   123  	data, ok := e.data.(map[string]interface{})
   124  	if !ok {
   125  		return nil, errors.New("field is not a group")
   126  	}
   127  
   128  	return &object{data: data}, nil
   129  }
   130  
   131  func (e *unmarshElem) Int32() (int32, error) {
   132  	i, ok := e.data.(int32)
   133  	if !ok {
   134  		return 0, fmt.Errorf("expected int32, found %T instead", e.data)
   135  	}
   136  	return i, nil
   137  }
   138  
   139  func (e *unmarshElem) Int64() (int64, error) {
   140  	i, ok := e.data.(int64)
   141  	if !ok {
   142  		return 0, fmt.Errorf("expected int64, found %T instead", e.data)
   143  	}
   144  	return i, nil
   145  }
   146  
   147  func (e *unmarshElem) Int96() ([12]byte, error) {
   148  	i, ok := e.data.([12]byte)
   149  	if !ok {
   150  		return [12]byte{}, fmt.Errorf("expected [12]byte, found %T instead", e.data)
   151  	}
   152  	return i, nil
   153  }
   154  
   155  func (e *unmarshElem) Float32() (float32, error) {
   156  	f, ok := e.data.(float32)
   157  	if !ok {
   158  		return 0, fmt.Errorf("expected float32, found %T instead", e.data)
   159  	}
   160  	return f, nil
   161  }
   162  
   163  func (e *unmarshElem) Float64() (float64, error) {
   164  	f, ok := e.data.(float64)
   165  	if !ok {
   166  		return 0, fmt.Errorf("expected float64, found %T instead", e.data)
   167  	}
   168  	return f, nil
   169  }
   170  
   171  func (e *unmarshElem) Bool() (bool, error) {
   172  	f, ok := e.data.(bool)
   173  	if !ok {
   174  		return false, fmt.Errorf("expected bool, found %T instead", e.data)
   175  	}
   176  	return f, nil
   177  }
   178  
   179  func (e *unmarshElem) ByteArray() ([]byte, error) {
   180  	f, ok := e.data.([]byte)
   181  	if !ok {
   182  		return nil, fmt.Errorf("expected []byte, found %T instead", e.data)
   183  	}
   184  	return f, nil
   185  }
   186  
   187  func (e *unmarshElem) List() (UnmarshalList, error) {
   188  	data, ok := e.data.(map[string]interface{})
   189  	if !ok {
   190  		return nil, fmt.Errorf("data is not a list, found %T instead", e.data)
   191  	}
   192  
   193  	isAthenaList := false
   194  	listData, ok := data["list"]
   195  	if !ok {
   196  		listData, ok = data["bag"]
   197  		if !ok {
   198  			return nil, errors.New("sub-group list or bag not found")
   199  		}
   200  		isAthenaList = true
   201  	}
   202  
   203  	elemList, ok := listData.([]map[string]interface{})
   204  	if !ok {
   205  		return nil, fmt.Errorf("expected sub-group list to be []map[string]interface{}, got %T instead", listData)
   206  	}
   207  
   208  	return &unmarshList{list: elemList, idx: -1, isAthenaList: isAthenaList}, nil
   209  }
   210  
   211  func (e *unmarshElem) Map() (UnmarshalMap, error) {
   212  	data, ok := e.data.(map[string]interface{})
   213  	if !ok {
   214  		return nil, fmt.Errorf("data is not a map, found %T instead", e.data)
   215  	}
   216  
   217  	kvData, ok := data["key_value"]
   218  	if !ok {
   219  		return nil, errors.New("sub-group key_value not found")
   220  	}
   221  
   222  	kvList, ok := kvData.([]map[string]interface{})
   223  	if !ok {
   224  		return nil, fmt.Errorf("expected sub-group key_value to be []map[string]interface{}, got %T instead", kvData)
   225  	}
   226  
   227  	return &unmarshMap{data: kvList, idx: -1}, nil
   228  }
   229  
   230  type unmarshList struct {
   231  	list         []map[string]interface{}
   232  	idx          int
   233  	isAthenaList bool
   234  }
   235  
   236  func (l *unmarshList) Next() bool {
   237  	l.idx++
   238  	return l.idx < len(l.list)
   239  }
   240  
   241  func (l *unmarshList) Value() (UnmarshalElement, error) {
   242  	if l.idx >= len(l.list) {
   243  		return nil, errors.New("iterator has reached end of list")
   244  	}
   245  
   246  	elemName := "element"
   247  	if l.isAthenaList {
   248  		elemName = "array_element"
   249  	}
   250  
   251  	elem, ok := l.list[l.idx][elemName]
   252  	if !ok {
   253  		return nil, fmt.Errorf("%s not found in current list element", elemName)
   254  	}
   255  
   256  	return &unmarshElem{data: elem}, nil
   257  }
   258  
   259  type unmarshMap struct {
   260  	data []map[string]interface{}
   261  	idx  int
   262  }
   263  
   264  func (m *unmarshMap) Next() bool {
   265  	m.idx++
   266  	return m.idx < len(m.data)
   267  }
   268  
   269  func (m *unmarshMap) Key() (UnmarshalElement, error) {
   270  	if m.idx >= len(m.data) {
   271  		return nil, errors.New("iterator has reached end of map")
   272  	}
   273  
   274  	elem, ok := m.data[m.idx]["key"]
   275  	if !ok {
   276  		return nil, errors.New("key not found in current map element")
   277  	}
   278  
   279  	return &unmarshElem{data: elem}, nil
   280  }
   281  
   282  func (m *unmarshMap) Value() (UnmarshalElement, error) {
   283  	if m.idx >= len(m.data) {
   284  		return nil, errors.New("iterator has reached end of map")
   285  	}
   286  
   287  	elem, ok := m.data[m.idx]["value"]
   288  	if !ok {
   289  		return nil, errors.New("value not found in current map element")
   290  	}
   291  
   292  	return &unmarshElem{data: elem}, nil
   293  }
   294  
   295  // NewUnmarshallObject creates a new unmarshaller object
   296  func NewUnmarshallObject(data map[string]interface{}) UnmarshalObject {
   297  	if data == nil {
   298  		data = make(map[string]interface{})
   299  	}
   300  	return &object{
   301  		data: data,
   302  	}
   303  }
   304  
   305  // NewUnmarshallElement creates new unmarshall element object
   306  func NewUnmarshallElement(data interface{}) UnmarshalElement {
   307  	return &unmarshElem{
   308  		data: data,
   309  	}
   310  }