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 }