Add starlark reader implementation
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				ci/woodpecker/push/woodpecker Pipeline was successful
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	ci/woodpecker/push/woodpecker Pipeline was successful
				
			This commit is contained in:
		
							
								
								
									
										87
									
								
								internal/convert/convert.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								internal/convert/convert.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
package convert
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"reflect"
 | 
			
		||||
 | 
			
		||||
	"go.starlark.net/starlark"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var ErrInvalidType = errors.New("unknown type")
 | 
			
		||||
 | 
			
		||||
func Convert(v any) (starlark.Value, error) {
 | 
			
		||||
	if v == nil {
 | 
			
		||||
		return starlark.None, nil
 | 
			
		||||
	}
 | 
			
		||||
	val := reflect.ValueOf(v)
 | 
			
		||||
	kind := val.Kind()
 | 
			
		||||
	for kind == reflect.Pointer || kind == reflect.Interface {
 | 
			
		||||
		val = val.Elem()
 | 
			
		||||
	}
 | 
			
		||||
	return convert(val)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func convert(val reflect.Value) (starlark.Value, error) {
 | 
			
		||||
	switch val.Kind() {
 | 
			
		||||
	case reflect.Interface:
 | 
			
		||||
		return convert(val.Elem())
 | 
			
		||||
	case reflect.Int, reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8:
 | 
			
		||||
		return starlark.MakeInt64(val.Int()), nil
 | 
			
		||||
	case reflect.Uint, reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8:
 | 
			
		||||
		return starlark.MakeUint64(val.Uint()), nil
 | 
			
		||||
	case reflect.Float64, reflect.Float32:
 | 
			
		||||
		return starlark.Float(val.Float()), nil
 | 
			
		||||
	case reflect.Bool:
 | 
			
		||||
		return starlark.Bool(val.Bool()), nil
 | 
			
		||||
	case reflect.String:
 | 
			
		||||
		return starlark.String(val.String()), nil
 | 
			
		||||
	case reflect.Slice, reflect.Array:
 | 
			
		||||
		return convertSlice(val)
 | 
			
		||||
	case reflect.Map:
 | 
			
		||||
		return convertMap(val)
 | 
			
		||||
	default:
 | 
			
		||||
		return nil, fmt.Errorf("%w: %s", ErrInvalidType, val.Type())
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func convertSlice(val reflect.Value) (starlark.Value, error) {
 | 
			
		||||
	// Detect byte slice
 | 
			
		||||
	if val.Type().Elem().Kind() == reflect.Uint8 {
 | 
			
		||||
		return starlark.Bytes(val.Bytes()), nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	elems := make([]starlark.Value, val.Len())
 | 
			
		||||
 | 
			
		||||
	for i := 0; i < val.Len(); i++ {
 | 
			
		||||
		elem, err := convert(val.Index(i))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		elems[i] = elem
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return starlark.NewList(elems), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func convertMap(val reflect.Value) (starlark.Value, error) {
 | 
			
		||||
	dict := starlark.NewDict(val.Len())
 | 
			
		||||
	iter := val.MapRange()
 | 
			
		||||
	for iter.Next() {
 | 
			
		||||
		k, err := convert(iter.Key())
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		v, err := convert(iter.Value())
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		err = dict.SetKey(k, v)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return dict, nil
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user