github.com/Comcast/plax@v0.8.32/dsl/subst.go (about)

     1  package dsl
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"regexp"
     8  
     9  	"github.com/Comcast/plax/subst"
    10  )
    11  
    12  func maybeUnmarshalString(s string) (string, bool) {
    13  	var x interface{}
    14  	if err := json.Unmarshal([]byte(s), &x); err == nil {
    15  		if s, is := x.(string); is {
    16  			return s, true
    17  		}
    18  	}
    19  	return s, false
    20  }
    21  
    22  func maybeMarshalString(s string, maybe bool) (string, error) {
    23  	if !maybe {
    24  		return s, nil
    25  	}
    26  	js, err := subst.JSONMarshal(&s)
    27  	if err != nil {
    28  		return "", err
    29  	}
    30  	return string(js), nil
    31  }
    32  
    33  var atAtFilename = regexp.MustCompile(`"?{@@(.+?)}"?`)
    34  
    35  func atAtSub(ctx *Ctx, s string) (string, error) {
    36  	s, un := maybeUnmarshalString(s)
    37  
    38  	var err error
    39  	y := atAtFilename.ReplaceAllStringFunc(s, func(s string) string {
    40  		m := atAtFilename.FindStringSubmatch(s)
    41  		if len(m) != 2 {
    42  			err = Brokenf("internal error: failed to @@ submatch on '%s'", s)
    43  			return fmt.Sprintf("<error: %s>", err)
    44  		}
    45  		filename := m[1]
    46  		var bs []byte
    47  		if bs, err = ioutil.ReadFile(ctx.Dir + "/" + filename); err != nil {
    48  			return fmt.Sprintf("<error: %s>", err)
    49  		}
    50  		return string(bs)
    51  	})
    52  	if err != nil {
    53  		return "", err
    54  	}
    55  
    56  	if y, err = maybeMarshalString(y, un); err != nil {
    57  		return "", err
    58  	}
    59  
    60  	return y, nil
    61  }
    62  
    63  var bangBangFilename = regexp.MustCompile(`"?{!!(.+?)!!}"?`)
    64  
    65  func bangBangSub(ctx *Ctx, s string) (string, error) {
    66  	s, un := maybeUnmarshalString(s)
    67  
    68  	var err error
    69  	y := bangBangFilename.ReplaceAllStringFunc(s, func(s string) string {
    70  		m := bangBangFilename.FindStringSubmatch(s)
    71  		if len(m) != 2 {
    72  			err = Brokenf("internal error: failed to !! submatch on '%s'", s)
    73  			return fmt.Sprintf("<error: %s>", err)
    74  		}
    75  		src := m[1]
    76  		ctx.Inddf("    Expansion: Javascript '%s'", short(src))
    77  		var x interface{}
    78  		if x, err = JSExec(ctx, src, nil); err != nil {
    79  			return fmt.Sprintf("<error: %s>", err)
    80  		}
    81  		str, is := x.(string)
    82  		if !is {
    83  			var js []byte
    84  			if js, err = subst.JSONMarshal(&x); err != nil {
    85  				return fmt.Sprintf("<error: %s>", err)
    86  			}
    87  			str = string(js)
    88  		}
    89  		return str
    90  	})
    91  	if err != nil {
    92  		return "", err
    93  	}
    94  	if y, err = maybeMarshalString(y, un); err != nil {
    95  		return "", err
    96  	}
    97  
    98  	return y, nil
    99  }