github.com/mavryk-network/mvgo@v1.19.9/internal/compose/variables.go (about)

     1  // Copyright (c) 2023 Blockwatch Data Inc.
     2  // Author: alex@blockwatch.cc, abdul@blockwatch.cc
     3  
     4  package compose
     5  
     6  import (
     7  	"fmt"
     8  	"regexp"
     9  	"strconv"
    10  	"strings"
    11  	"time"
    12  )
    13  
    14  const (
    15  	VAR_PREFIX  = "$"
    16  	FILE_PREFIX = "@"
    17  	TIME_PREFIX = "$now"
    18  )
    19  
    20  var NESTED_VAR = regexp.MustCompile(`\$[a-zA-Z0-9_-]+`)
    21  
    22  func (c Context) ResolveNestedVars(src string) (string, bool) {
    23  	if NESTED_VAR.MatchString(src) {
    24  		return NESTED_VAR.ReplaceAllStringFunc(src, func(v string) string {
    25  			if val, ok := c.Variables[v]; ok {
    26  				return val
    27  			}
    28  			return v
    29  		}), true
    30  	}
    31  	return src, false
    32  }
    33  
    34  func CreateVariable(v string) string {
    35  	if IsVariable(v) {
    36  		return v
    37  	}
    38  	return VAR_PREFIX + v
    39  }
    40  
    41  func IsVariable(v string) bool {
    42  	return strings.HasPrefix(v, VAR_PREFIX)
    43  }
    44  
    45  func IsTimeExpression(v string) bool {
    46  	return strings.HasPrefix(v, TIME_PREFIX)
    47  }
    48  
    49  func IsFile(v string) bool {
    50  	return strings.HasPrefix(v, FILE_PREFIX)
    51  }
    52  
    53  func ConvertTime(v string) (string, error) {
    54  	if IsTimeExpression(v) {
    55  		v = strings.TrimPrefix(v, "$now")
    56  		t := time.Now().UTC()
    57  		if len(v) == 0 {
    58  			return t.Format(time.RFC3339), nil
    59  		}
    60  		switch v[0] {
    61  		case '-':
    62  			d, err := time.ParseDuration(v[1:])
    63  			if err != nil {
    64  				return "", err
    65  			}
    66  			return t.Add(-d).Format(time.RFC3339), nil
    67  		case '+':
    68  			d, err := time.ParseDuration(v[1:])
    69  			if err != nil {
    70  				return "", err
    71  			}
    72  			return t.Add(d).Format(time.RFC3339), nil
    73  		default:
    74  			return "", fmt.Errorf("invalid time offset")
    75  		}
    76  	}
    77  	t, err := ParseTime(v)
    78  	if err != nil {
    79  		return "", err
    80  	}
    81  	return t.Format(time.RFC3339), nil
    82  }
    83  
    84  func ParseTime(v string) (time.Time, error) {
    85  	if i, err := strconv.ParseInt(v, 10, 64); err == nil {
    86  		return time.Unix(i, 0), nil
    87  	}
    88  	for _, f := range []string{
    89  		time.RFC3339,
    90  		time.RFC3339Nano,
    91  		"2006-01-02T15:04:05.999999999Z",
    92  		"2006-01-02T15:04:05Z",
    93  		"2006-01-02T15:04:05.999999999",
    94  		"2006-01-02T15:04:05",
    95  	} {
    96  		if t, err := time.Parse(f, v); err == nil {
    97  			return t.UTC(), nil
    98  		}
    99  	}
   100  	return time.Time{}, fmt.Errorf("invalid time format")
   101  }