github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/utils/objectkeys/objectkeys.go (about)

     1  package objectkeys
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strconv"
     7  
     8  	"github.com/lmorg/murex/lang"
     9  )
    10  
    11  func Recursive(ctx context.Context, path string, v interface{}, separator string, writeString func(string) error, iteration int) error {
    12  	if iteration == 0 {
    13  		return nil
    14  	}
    15  
    16  	switch t := v.(type) {
    17  	case []string:
    18  		for i := range t {
    19  			select {
    20  			case <-ctx.Done():
    21  				return nil
    22  			default:
    23  			}
    24  
    25  			err := writeString(path + separator + strconv.Itoa(i))
    26  			if err != nil {
    27  				return err
    28  			}
    29  		}
    30  		return nil
    31  
    32  	case []int:
    33  		for i := range t {
    34  			select {
    35  			case <-ctx.Done():
    36  				return nil
    37  			default:
    38  			}
    39  
    40  			err := writeString(path + separator + strconv.Itoa(i))
    41  			if err != nil {
    42  				return err
    43  			}
    44  		}
    45  		return nil
    46  
    47  	case []float64:
    48  		for i := range t {
    49  			select {
    50  			case <-ctx.Done():
    51  				return nil
    52  			default:
    53  			}
    54  
    55  			err := writeString(path + separator + strconv.Itoa(i))
    56  			if err != nil {
    57  				return err
    58  			}
    59  		}
    60  		return nil
    61  
    62  	case []uint32:
    63  		for i := range t {
    64  			select {
    65  			case <-ctx.Done():
    66  				return nil
    67  			default:
    68  			}
    69  
    70  			err := writeString(path + separator + strconv.Itoa(i))
    71  			if err != nil {
    72  				return err
    73  			}
    74  		}
    75  		return nil
    76  
    77  	case []bool:
    78  		for i := range t {
    79  			select {
    80  			case <-ctx.Done():
    81  				return nil
    82  			default:
    83  			}
    84  
    85  			err := writeString(path + separator + strconv.Itoa(i))
    86  			if err != nil {
    87  				return err
    88  			}
    89  		}
    90  		return nil
    91  
    92  	case []interface{}:
    93  		for i := range t {
    94  			select {
    95  			case <-ctx.Done():
    96  				return nil
    97  			default:
    98  			}
    99  
   100  			newPath := path + separator + strconv.Itoa(i)
   101  			err := writeString(newPath)
   102  			if err != nil {
   103  				return err
   104  			}
   105  			err = Recursive(ctx, newPath, t[i], separator, writeString, iteration-1)
   106  			if err != nil {
   107  				return err
   108  			}
   109  		}
   110  		return nil
   111  
   112  	case [][]string:
   113  		for i := range t {
   114  			select {
   115  			case <-ctx.Done():
   116  				return nil
   117  			default:
   118  			}
   119  
   120  			newPath := path + separator + strconv.Itoa(i)
   121  			err := writeString(newPath)
   122  			if err != nil {
   123  				return err
   124  			}
   125  			err = Recursive(ctx, newPath, t[i], separator, writeString, iteration-1)
   126  			if err != nil {
   127  				return err
   128  			}
   129  		}
   130  		return nil
   131  
   132  	case map[string]interface{}:
   133  		for key := range t {
   134  			select {
   135  			case <-ctx.Done():
   136  				return nil
   137  			default:
   138  			}
   139  
   140  			newPath := path + separator + key
   141  			err := writeString(newPath)
   142  			if err != nil {
   143  				return err
   144  			}
   145  			err = Recursive(ctx, newPath, t[key], separator, writeString, iteration-1)
   146  			if err != nil {
   147  				return err
   148  			}
   149  		}
   150  		return nil
   151  
   152  	case map[int]interface{}:
   153  		for key := range t {
   154  			select {
   155  			case <-ctx.Done():
   156  				return nil
   157  			default:
   158  			}
   159  
   160  			newPath := path + separator + strconv.Itoa(key)
   161  			err := writeString(newPath)
   162  			if err != nil {
   163  				return err
   164  			}
   165  			err = Recursive(ctx, newPath, t[key], separator, writeString, iteration-1)
   166  			if err != nil {
   167  				return err
   168  			}
   169  		}
   170  		return nil
   171  
   172  	case map[interface{}]interface{}:
   173  		for key := range t {
   174  			select {
   175  			case <-ctx.Done():
   176  				return nil
   177  			default:
   178  			}
   179  
   180  			newPath := path + separator + fmt.Sprint(key)
   181  			err := writeString(newPath)
   182  			if err != nil {
   183  				return err
   184  			}
   185  			err = Recursive(ctx, newPath, t[key], separator, writeString, iteration-1)
   186  			if err != nil {
   187  				return err
   188  			}
   189  		}
   190  		return nil
   191  
   192  	case string, bool, int, float64, nil, float32, uint, int8, int16, int32, int64, uint8, uint16, uint32, uint64:
   193  		return nil
   194  
   195  	case lang.MxInterface:
   196  		return Recursive(ctx, path, t.GetValue(), separator, writeString, iteration)
   197  
   198  	default:
   199  		return fmt.Errorf("found %T but no case exists for handling it", t)
   200  	}
   201  }