go-cty: github.com/zclconf/go-cty/cty/function/stdlib Index | Files

package stdlib

import "github.com/zclconf/go-cty/cty/function/stdlib"

Package stdlib is a collection of cty functions that are expected to be generally useful, and are thus factored out into this shared library in the hope that cty-using applications will have consistent behavior when using these functions.

See the parent package "function" for more information on the purpose and usage of cty functions.

This package contains both Go functions, which provide convenient access to call the functions from Go code, and the Function objects themselves. The latter follow the naming scheme of appending "Func" to the end of the function name.

Index

Package Files

bool.go bytes.go collection.go csv.go datetime.go doc.go format.go format_fsm.go general.go json.go number.go regexp.go sequence.go set.go string.go

Variables

var AbsoluteFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "num",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.Number),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        return args[0].Absolute(), nil
    },
})
var AddFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "a",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
        {
            Name:             "b",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.Number),
    Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {

        defer func() {
            if r := recover(); r != nil {
                if _, ok := r.(big.ErrNaN); ok {
                    ret = cty.NilVal
                    err = fmt.Errorf("can't compute sum of opposing infinities")
                } else {

                    panic(r)
                }
            }
        }()
        return args[0].Add(args[1]), nil
    },
})
var AndFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "a",
            Type:             cty.Bool,
            AllowDynamicType: true,
        },
        {
            Name:             "b",
            Type:             cty.Bool,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.Bool),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        return args[0].And(args[1]), nil
    },
})
var Bytes = cty.Capsule("bytes", reflect.TypeOf([]byte(nil)))

Bytes is a capsule type that can be used with the binary functions to support applications that need to support raw buffers in addition to UTF-8 strings.

var BytesLenFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "buf",
            Type:             Bytes,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.Number),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        bufPtr := args[0].EncapsulatedValue().(*[]byte)
        return cty.NumberIntVal(int64(len(*bufPtr))), nil
    },
})

BytesLen is a Function that returns the length of the buffer encapsulated in a Bytes value.

var BytesSliceFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "buf",
            Type:             Bytes,
            AllowDynamicType: true,
        },
        {
            Name:             "offset",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
        {
            Name:             "length",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(Bytes),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        bufPtr := args[0].EncapsulatedValue().(*[]byte)

        var offset, length int

        var err error
        err = gocty.FromCtyValue(args[1], &offset)
        if err != nil {
            return cty.NilVal, err
        }
        err = gocty.FromCtyValue(args[2], &length)
        if err != nil {
            return cty.NilVal, err
        }

        if offset < 0 || length < 0 {
            return cty.NilVal, fmt.Errorf("offset and length must be non-negative")
        }

        if offset > len(*bufPtr) {
            return cty.NilVal, fmt.Errorf(
                "offset %d is greater than total buffer length %d",
                offset, len(*bufPtr),
            )
        }

        end := offset + length

        if end > len(*bufPtr) {
            return cty.NilVal, fmt.Errorf(
                "offset %d + length %d is greater than total buffer length %d",
                offset, length, len(*bufPtr),
            )
        }

        return BytesVal((*bufPtr)[offset:end]), nil
    },
})

BytesSlice is a Function that returns a slice of the given Bytes value.

var CSVDecodeFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name: "str",
            Type: cty.String,
        },
    },
    Type: func(args []cty.Value) (cty.Type, error) {
        str := args[0]
        if !str.IsKnown() {
            return cty.DynamicPseudoType, nil
        }

        r := strings.NewReader(str.AsString())
        cr := csv.NewReader(r)
        headers, err := cr.Read()
        if err == io.EOF {
            return cty.DynamicPseudoType, fmt.Errorf("missing header line")
        }
        if err != nil {
            return cty.DynamicPseudoType, err
        }

        atys := make(map[string]cty.Type, len(headers))
        for _, name := range headers {
            if _, exists := atys[name]; exists {
                return cty.DynamicPseudoType, fmt.Errorf("duplicate column name %q", name)
            }
            atys[name] = cty.String
        }
        return cty.List(cty.Object(atys)), nil
    },
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        ety := retType.ElementType()
        atys := ety.AttributeTypes()
        str := args[0]
        r := strings.NewReader(str.AsString())
        cr := csv.NewReader(r)
        cr.FieldsPerRecord = len(atys)

        headers, err := cr.Read()
        if err != nil {
            return cty.DynamicVal, err
        }

        var rows []cty.Value
        for {
            cols, err := cr.Read()
            if err == io.EOF {
                break
            }
            if err != nil {
                return cty.DynamicVal, err
            }

            vals := make(map[string]cty.Value, len(cols))
            for i, str := range cols {
                name := headers[i]
                vals[name] = cty.StringVal(str)
            }
            rows = append(rows, cty.ObjectVal(vals))
        }

        if len(rows) == 0 {
            return cty.ListValEmpty(ety), nil
        }
        return cty.ListVal(rows), nil
    },
})
var CoalesceFunc = function.New(&function.Spec{
    Params: []function.Parameter{},
    VarParam: &function.Parameter{
        Name:             "vals",
        Type:             cty.DynamicPseudoType,
        AllowUnknown:     true,
        AllowDynamicType: true,
        AllowNull:        true,
    },
    Type: func(args []cty.Value) (ret cty.Type, err error) {
        argTypes := make([]cty.Type, len(args))
        for i, val := range args {
            argTypes[i] = val.Type()
        }
        retType, _ := convert.UnifyUnsafe(argTypes)
        if retType == cty.NilType {
            return cty.NilType, fmt.Errorf("all arguments must have the same type")
        }
        return retType, nil
    },
    Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
        for _, argVal := range args {
            if !argVal.IsKnown() {
                return cty.UnknownVal(retType), nil
            }
            if argVal.IsNull() {
                continue
            }

            return convert.Convert(argVal, retType)
        }
        return cty.NilVal, fmt.Errorf("no non-null arguments")
    },
})
var ConcatFunc = function.New(&function.Spec{
    Params: []function.Parameter{},
    VarParam: &function.Parameter{
        Name: "seqs",
        Type: cty.DynamicPseudoType,
    },
    Type: func(args []cty.Value) (ret cty.Type, err error) {
        if len(args) == 0 {
            return cty.NilType, fmt.Errorf("at least one argument is required")
        }

        if args[0].Type().IsListType() {

            tys := make([]cty.Type, len(args))
            for i, val := range args {
                ty := val.Type()
                if !ty.IsListType() {
                    tys = nil
                    break
                }
                tys[i] = ty
            }

            if tys != nil {
                commonType, _ := convert.UnifyUnsafe(tys)
                if commonType != cty.NilType {
                    return commonType, nil
                }
            }
        }

        etys := make([]cty.Type, 0, len(args))
        for i, val := range args {
            ety := val.Type()
            switch {
            case ety.IsTupleType():
                etys = append(etys, ety.TupleElementTypes()...)
            case ety.IsListType():
                if !val.IsKnown() {

                    return cty.DynamicPseudoType, nil
                }

                l := val.LengthInt()
                subEty := ety.ElementType()
                for j := 0; j < l; j++ {
                    etys = append(etys, subEty)
                }
            default:
                return cty.NilType, function.NewArgErrorf(
                    i, "all arguments must be lists or tuples; got %s",
                    ety.FriendlyName(),
                )
            }
        }
        return cty.Tuple(etys), nil
    },
    Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
        switch {
        case retType.IsListType():

            vals := make([]cty.Value, 0, len(args))
            for i, list := range args {
                list, err = convert.Convert(list, retType)
                if err != nil {

                    return cty.NilVal, function.NewArgError(i, err)
                }

                it := list.ElementIterator()
                for it.Next() {
                    _, v := it.Element()
                    vals = append(vals, v)
                }
            }
            if len(vals) == 0 {
                return cty.ListValEmpty(retType.ElementType()), nil
            }

            return cty.ListVal(vals), nil
        case retType.IsTupleType():

            vals := make([]cty.Value, 0, len(args))

            for _, seq := range args {

                it := seq.ElementIterator()
                for it.Next() {
                    _, v := it.Element()
                    vals = append(vals, v)
                }
            }

            return cty.TupleVal(vals), nil
        default:

            panic("unsupported return type")
        }
    },
})
var DivideFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "a",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
        {
            Name:             "b",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.Number),
    Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {

        defer func() {
            if r := recover(); r != nil {
                if _, ok := r.(big.ErrNaN); ok {
                    ret = cty.NilVal
                    err = fmt.Errorf("can't divide zero by zero or infinity by infinity")
                } else {

                    panic(r)
                }
            }
        }()

        return args[0].Divide(args[1]), nil
    },
})
var EqualFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "a",
            Type:             cty.DynamicPseudoType,
            AllowUnknown:     true,
            AllowDynamicType: true,
            AllowNull:        true,
        },
        {
            Name:             "b",
            Type:             cty.DynamicPseudoType,
            AllowUnknown:     true,
            AllowDynamicType: true,
            AllowNull:        true,
        },
    },
    Type: function.StaticReturnType(cty.Bool),
    Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
        return args[0].Equals(args[1]), nil
    },
})
var FormatDateFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name: "format",
            Type: cty.String,
        },
        {
            Name: "time",
            Type: cty.String,
        },
    },
    Type: function.StaticReturnType(cty.String),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        formatStr := args[0].AsString()
        timeStr := args[1].AsString()
        t, err := parseTimestamp(timeStr)
        if err != nil {
            return cty.DynamicVal, function.NewArgError(1, err)
        }

        var buf bytes.Buffer
        sc := bufio.NewScanner(strings.NewReader(formatStr))
        sc.Split(splitDateFormat)
        const esc = '\''
        for sc.Scan() {
            tok := sc.Bytes()

            switch {
            case tok[0] == esc:
                if tok[len(tok)-1] != esc || len(tok) == 1 {
                    return cty.DynamicVal, function.NewArgErrorf(0, "unterminated literal '")
                }
                if len(tok) == 2 {

                    buf.WriteByte(esc)
                } else {

                    raw := tok[1 : len(tok)-1]
                    for i := 0; i < len(raw); i++ {
                        buf.WriteByte(raw[i])
                        if raw[i] == esc {
                            i++
                        }
                    }
                }

            case startsDateFormatVerb(tok[0]):
                switch tok[0] {
                case 'Y':
                    y := t.Year()
                    switch len(tok) {
                    case 2:
                        fmt.Fprintf(&buf, "%02d", y%100)
                    case 4:
                        fmt.Fprintf(&buf, "%04d", y)
                    default:
                        return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: year must either be \"YY\" or \"YYYY\"", tok)
                    }
                case 'M':
                    m := t.Month()
                    switch len(tok) {
                    case 1:
                        fmt.Fprintf(&buf, "%d", m)
                    case 2:
                        fmt.Fprintf(&buf, "%02d", m)
                    case 3:
                        buf.WriteString(m.String()[:3])
                    case 4:
                        buf.WriteString(m.String())
                    default:
                        return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: month must be \"M\", \"MM\", \"MMM\", or \"MMMM\"", tok)
                    }
                case 'D':
                    d := t.Day()
                    switch len(tok) {
                    case 1:
                        fmt.Fprintf(&buf, "%d", d)
                    case 2:
                        fmt.Fprintf(&buf, "%02d", d)
                    default:
                        return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: day of month must either be \"D\" or \"DD\"", tok)
                    }
                case 'E':
                    d := t.Weekday()
                    switch len(tok) {
                    case 3:
                        buf.WriteString(d.String()[:3])
                    case 4:
                        buf.WriteString(d.String())
                    default:
                        return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: day of week must either be \"EEE\" or \"EEEE\"", tok)
                    }
                case 'h':
                    h := t.Hour()
                    switch len(tok) {
                    case 1:
                        fmt.Fprintf(&buf, "%d", h)
                    case 2:
                        fmt.Fprintf(&buf, "%02d", h)
                    default:
                        return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: 24-hour must either be \"h\" or \"hh\"", tok)
                    }
                case 'H':
                    h := t.Hour() % 12
                    if h == 0 {
                        h = 12
                    }
                    switch len(tok) {
                    case 1:
                        fmt.Fprintf(&buf, "%d", h)
                    case 2:
                        fmt.Fprintf(&buf, "%02d", h)
                    default:
                        return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: 12-hour must either be \"H\" or \"HH\"", tok)
                    }
                case 'A', 'a':
                    if len(tok) != 2 {
                        return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: must be \"%s%s\"", tok, tok[0:1], tok[0:1])
                    }
                    upper := tok[0] == 'A'
                    switch t.Hour() / 12 {
                    case 0:
                        if upper {
                            buf.WriteString("AM")
                        } else {
                            buf.WriteString("am")
                        }
                    case 1:
                        if upper {
                            buf.WriteString("PM")
                        } else {
                            buf.WriteString("pm")
                        }
                    }
                case 'm':
                    m := t.Minute()
                    switch len(tok) {
                    case 1:
                        fmt.Fprintf(&buf, "%d", m)
                    case 2:
                        fmt.Fprintf(&buf, "%02d", m)
                    default:
                        return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: minute must either be \"m\" or \"mm\"", tok)
                    }
                case 's':
                    s := t.Second()
                    switch len(tok) {
                    case 1:
                        fmt.Fprintf(&buf, "%d", s)
                    case 2:
                        fmt.Fprintf(&buf, "%02d", s)
                    default:
                        return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: second must either be \"s\" or \"ss\"", tok)
                    }
                case 'Z':

                    switch len(tok) {
                    case 1:
                        buf.WriteString(t.Format("Z07:00"))
                    case 3:
                        str := t.Format("-0700")
                        switch str {
                        case "+0000":
                            buf.WriteString("UTC")
                        default:
                            buf.WriteString(str)
                        }
                    case 4:
                        buf.WriteString(t.Format("-0700"))
                    case 5:
                        buf.WriteString(t.Format("-07:00"))
                    default:
                        return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: timezone must be Z, ZZZZ, or ZZZZZ", tok)
                    }
                default:
                    return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q", tok)
                }

            default:

                buf.Write(tok)
            }
        }

        return cty.StringVal(buf.String()), nil
    },
})
var FormatFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name: "format",
            Type: cty.String,
        },
    },
    VarParam: &function.Parameter{
        Name:      "args",
        Type:      cty.DynamicPseudoType,
        AllowNull: true,
    },
    Type: function.StaticReturnType(cty.String),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        for _, arg := range args[1:] {
            if !arg.IsWhollyKnown() {

                return cty.UnknownVal(cty.String), nil
            }
        }
        str, err := formatFSM(args[0].AsString(), args[1:])
        return cty.StringVal(str), err
    },
})
var FormatListFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name: "format",
            Type: cty.String,
        },
    },
    VarParam: &function.Parameter{
        Name:         "args",
        Type:         cty.DynamicPseudoType,
        AllowNull:    true,
        AllowUnknown: true,
    },
    Type: function.StaticReturnType(cty.List(cty.String)),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        fmtVal := args[0]
        args = args[1:]

        if len(args) == 0 {

            result, err := Format(fmtVal, args...)
            return cty.ListVal([]cty.Value{result}), err
        }

        fmtStr := fmtVal.AsString()

        iterLen := -1
        lenChooser := -1
        iterators := make([]cty.ElementIterator, len(args))
        singleVals := make([]cty.Value, len(args))
        unknowns := make([]bool, len(args))
        for i, arg := range args {
            argTy := arg.Type()
            switch {
            case (argTy.IsListType() || argTy.IsSetType() || argTy.IsTupleType()) && !arg.IsNull():
                if !argTy.IsTupleType() && !arg.IsKnown() {

                    unknowns[i] = true
                    continue
                }
                thisLen := arg.LengthInt()
                if iterLen == -1 {
                    iterLen = thisLen
                    lenChooser = i
                } else {
                    if thisLen != iterLen {
                        return cty.NullVal(cty.List(cty.String)), function.NewArgErrorf(
                            i+1,
                            "argument %d has length %d, which is inconsistent with argument %d of length %d",
                            i+1, thisLen,
                            lenChooser+1, iterLen,
                        )
                    }
                }
                if !arg.IsKnown() {

                    unknowns[i] = true
                    continue
                }
                iterators[i] = arg.ElementIterator()
            default:
                singleVals[i] = arg
            }
        }

        for _, isUnk := range unknowns {
            if isUnk {
                return cty.UnknownVal(retType), nil
            }
        }

        if iterLen == 0 {

            return cty.ListValEmpty(cty.String), nil
        }

        if iterLen == -1 {

            iterLen = 1
        }

        ret := make([]cty.Value, 0, iterLen)
        fmtArgs := make([]cty.Value, len(iterators))
    Results:
        for iterIdx := 0; iterIdx < iterLen; iterIdx++ {

            for i := range fmtArgs {
                switch {
                case iterators[i] != nil:
                    iterator := iterators[i]
                    iterator.Next()
                    _, val := iterator.Element()
                    fmtArgs[i] = val
                default:
                    fmtArgs[i] = singleVals[i]
                }

                if !fmtArgs[i].IsWhollyKnown() {

                    ret = append(ret, cty.UnknownVal(cty.String))
                    continue Results
                }
            }

            str, err := formatFSM(fmtStr, fmtArgs)
            if err != nil {
                return cty.NullVal(cty.List(cty.String)), fmt.Errorf(
                    "error on format iteration %d: %s", iterIdx, err,
                )
            }

            ret = append(ret, cty.StringVal(str))
        }

        return cty.ListVal(ret), nil
    },
})
var GreaterThanFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "a",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
        {
            Name:             "b",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.Bool),
    Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
        return args[0].GreaterThan(args[1]), nil
    },
})
var GreaterThanOrEqualToFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "a",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
        {
            Name:             "b",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.Bool),
    Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
        return args[0].GreaterThanOrEqualTo(args[1]), nil
    },
})
var HasIndexFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "collection",
            Type:             cty.DynamicPseudoType,
            AllowDynamicType: true,
        },
        {
            Name:             "key",
            Type:             cty.DynamicPseudoType,
            AllowDynamicType: true,
        },
    },
    Type: func(args []cty.Value) (ret cty.Type, err error) {
        collTy := args[0].Type()
        if !(collTy.IsTupleType() || collTy.IsListType() || collTy.IsMapType() || collTy == cty.DynamicPseudoType) {
            return cty.NilType, fmt.Errorf("collection must be a list, a map or a tuple")
        }
        return cty.Bool, nil
    },
    Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
        return args[0].HasIndex(args[1]), nil
    },
})
var IndexFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name: "collection",
            Type: cty.DynamicPseudoType,
        },
        {
            Name:             "key",
            Type:             cty.DynamicPseudoType,
            AllowDynamicType: true,
        },
    },
    Type: func(args []cty.Value) (ret cty.Type, err error) {
        collTy := args[0].Type()
        key := args[1]
        keyTy := key.Type()
        switch {
        case collTy.IsTupleType():
            if keyTy != cty.Number && keyTy != cty.DynamicPseudoType {
                return cty.NilType, fmt.Errorf("key for tuple must be number")
            }
            if !key.IsKnown() {
                return cty.DynamicPseudoType, nil
            }
            var idx int
            err := gocty.FromCtyValue(key, &idx)
            if err != nil {
                return cty.NilType, fmt.Errorf("invalid key for tuple: %s", err)
            }

            etys := collTy.TupleElementTypes()

            if idx >= len(etys) || idx < 0 {
                return cty.NilType, fmt.Errorf("key must be between 0 and %d inclusive", len(etys))
            }

            return etys[idx], nil

        case collTy.IsListType():
            if keyTy != cty.Number && keyTy != cty.DynamicPseudoType {
                return cty.NilType, fmt.Errorf("key for list must be number")
            }

            return collTy.ElementType(), nil

        case collTy.IsMapType():
            if keyTy != cty.String && keyTy != cty.DynamicPseudoType {
                return cty.NilType, fmt.Errorf("key for map must be string")
            }

            return collTy.ElementType(), nil

        default:
            return cty.NilType, fmt.Errorf("collection must be a list, a map or a tuple")
        }
    },
    Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
        has, err := HasIndex(args[0], args[1])
        if err != nil {
            return cty.NilVal, err
        }
        if has.False() {
            return cty.NilVal, fmt.Errorf("invalid index")
        }

        return args[0].Index(args[1]), nil
    },
})
var IntFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "num",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.Number),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        bf := args[0].AsBigFloat()
        if bf.IsInt() {
            return args[0], nil
        }
        bi, _ := bf.Int(nil)
        bf = (&big.Float{}).SetInt(bi)
        return cty.NumberVal(bf), nil
    },
})
var JSONDecodeFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name: "str",
            Type: cty.String,
        },
    },
    Type: func(args []cty.Value) (cty.Type, error) {
        str := args[0]
        if !str.IsKnown() {
            return cty.DynamicPseudoType, nil
        }

        buf := []byte(str.AsString())
        return json.ImpliedType(buf)
    },
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        buf := []byte(args[0].AsString())
        return json.Unmarshal(buf, retType)
    },
})
var JSONEncodeFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "val",
            Type:             cty.DynamicPseudoType,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.String),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        val := args[0]
        if !val.IsWhollyKnown() {

            return cty.UnknownVal(retType), nil
        }

        buf, err := json.Marshal(val, val.Type())
        if err != nil {
            return cty.NilVal, err
        }

        return cty.StringVal(string(buf)), nil
    },
})
var LengthFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "collection",
            Type:             cty.DynamicPseudoType,
            AllowDynamicType: true,
        },
    },
    Type: func(args []cty.Value) (ret cty.Type, err error) {
        collTy := args[0].Type()
        if !(collTy.IsTupleType() || collTy.IsListType() || collTy.IsMapType() || collTy.IsSetType() || collTy == cty.DynamicPseudoType) {
            return cty.NilType, fmt.Errorf("collection must be a list, a map or a tuple")
        }
        return cty.Number, nil
    },
    Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
        return args[0].Length(), nil
    },
})
var LessThanFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "a",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
        {
            Name:             "b",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.Bool),
    Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
        return args[0].LessThan(args[1]), nil
    },
})
var LessThanOrEqualToFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "a",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
        {
            Name:             "b",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.Bool),
    Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
        return args[0].LessThanOrEqualTo(args[1]), nil
    },
})
var LowerFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "str",
            Type:             cty.String,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.String),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        in := args[0].AsString()
        out := strings.ToLower(in)
        return cty.StringVal(out), nil
    },
})
var MaxFunc = function.New(&function.Spec{
    Params: []function.Parameter{},
    VarParam: &function.Parameter{
        Name:             "numbers",
        Type:             cty.Number,
        AllowDynamicType: true,
    },
    Type: function.StaticReturnType(cty.Number),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        if len(args) == 0 {
            return cty.NilVal, fmt.Errorf("must pass at least one number")
        }

        max := cty.NegativeInfinity
        for _, num := range args {
            if num.GreaterThan(max).True() {
                max = num
            }
        }

        return max, nil
    },
})
var MinFunc = function.New(&function.Spec{
    Params: []function.Parameter{},
    VarParam: &function.Parameter{
        Name:             "numbers",
        Type:             cty.Number,
        AllowDynamicType: true,
    },
    Type: function.StaticReturnType(cty.Number),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        if len(args) == 0 {
            return cty.NilVal, fmt.Errorf("must pass at least one number")
        }

        min := cty.PositiveInfinity
        for _, num := range args {
            if num.LessThan(min).True() {
                min = num
            }
        }

        return min, nil
    },
})
var ModuloFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "a",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
        {
            Name:             "b",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.Number),
    Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {

        defer func() {
            if r := recover(); r != nil {
                if _, ok := r.(big.ErrNaN); ok {
                    ret = cty.NilVal
                    err = fmt.Errorf("can't use modulo with zero and infinity")
                } else {

                    panic(r)
                }
            }
        }()

        return args[0].Modulo(args[1]), nil
    },
})
var MultiplyFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "a",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
        {
            Name:             "b",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.Number),
    Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {

        defer func() {
            if r := recover(); r != nil {
                if _, ok := r.(big.ErrNaN); ok {
                    ret = cty.NilVal
                    err = fmt.Errorf("can't multiply zero by infinity")
                } else {

                    panic(r)
                }
            }
        }()

        return args[0].Multiply(args[1]), nil
    },
})
var NegateFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "num",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.Number),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        return args[0].Negate(), nil
    },
})
var NotEqualFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "a",
            Type:             cty.DynamicPseudoType,
            AllowUnknown:     true,
            AllowDynamicType: true,
            AllowNull:        true,
        },
        {
            Name:             "b",
            Type:             cty.DynamicPseudoType,
            AllowUnknown:     true,
            AllowDynamicType: true,
            AllowNull:        true,
        },
    },
    Type: function.StaticReturnType(cty.Bool),
    Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
        return args[0].Equals(args[1]).Not(), nil
    },
})
var NotFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "val",
            Type:             cty.Bool,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.Bool),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        return args[0].Not(), nil
    },
})
var OrFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "a",
            Type:             cty.Bool,
            AllowDynamicType: true,
        },
        {
            Name:             "b",
            Type:             cty.Bool,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.Bool),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        return args[0].Or(args[1]), nil
    },
})
var RangeFunc = function.New(&function.Spec{
    VarParam: &function.Parameter{
        Name: "params",
        Type: cty.Number,
    },
    Type: function.StaticReturnType(cty.List(cty.Number)),
    Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
        var start, end, step cty.Value
        switch len(args) {
        case 1:
            if args[0].LessThan(cty.Zero).True() {
                start, end, step = cty.Zero, args[0], cty.NumberIntVal(-1)
            } else {
                start, end, step = cty.Zero, args[0], cty.NumberIntVal(1)
            }
        case 2:
            if args[1].LessThan(args[0]).True() {
                start, end, step = args[0], args[1], cty.NumberIntVal(-1)
            } else {
                start, end, step = args[0], args[1], cty.NumberIntVal(1)
            }
        case 3:
            start, end, step = args[0], args[1], args[2]
        default:
            return cty.NilVal, fmt.Errorf("must have one, two, or three arguments")
        }

        var vals []cty.Value

        if step == cty.Zero {
            return cty.NilVal, function.NewArgErrorf(2, "step must not be zero")
        }
        down := step.LessThan(cty.Zero).True()

        if down {
            if end.GreaterThan(start).True() {
                return cty.NilVal, function.NewArgErrorf(1, "end must be less than start when step is negative")
            }
        } else {
            if end.LessThan(start).True() {
                return cty.NilVal, function.NewArgErrorf(1, "end must be greater than start when step is positive")
            }
        }

        num := start
        for {
            if down {
                if num.LessThanOrEqualTo(end).True() {
                    break
                }
            } else {
                if num.GreaterThanOrEqualTo(end).True() {
                    break
                }
            }
            if len(vals) >= 1024 {

                return cty.NilVal, fmt.Errorf("more than 1024 values were generated; either decrease the difference between start and end or use a smaller step")
            }
            vals = append(vals, num)
            num = num.Add(step)
        }
        if len(vals) == 0 {
            return cty.ListValEmpty(cty.Number), nil
        }
        return cty.ListVal(vals), nil
    },
})
var RegexAllFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name: "pattern",
            Type: cty.String,
        },
        {
            Name: "string",
            Type: cty.String,
        },
    },
    Type: func(args []cty.Value) (cty.Type, error) {
        if !args[0].IsKnown() {

            return cty.List(cty.DynamicPseudoType), nil
        }

        retTy, err := regexPatternResultType(args[0].AsString())
        if err != nil {
            err = function.NewArgError(0, err)
        }
        return cty.List(retTy), err
    },
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        ety := retType.ElementType()
        if ety == cty.DynamicPseudoType {
            return cty.DynamicVal, nil
        }

        re, err := regexp.Compile(args[0].AsString())
        if err != nil {

            return cty.NilVal, function.NewArgErrorf(0, "error parsing pattern: %s", err)
        }
        str := args[1].AsString()

        captureIdxsEach := re.FindAllStringSubmatchIndex(str, -1)
        if len(captureIdxsEach) == 0 {
            return cty.ListValEmpty(ety), nil
        }

        elems := make([]cty.Value, len(captureIdxsEach))
        for i, captureIdxs := range captureIdxsEach {
            elems[i] = regexPatternResult(re, str, captureIdxs, ety)
        }
        return cty.ListVal(elems), nil
    },
})
var RegexFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name: "pattern",
            Type: cty.String,
        },
        {
            Name: "string",
            Type: cty.String,
        },
    },
    Type: func(args []cty.Value) (cty.Type, error) {
        if !args[0].IsKnown() {

            return cty.DynamicPseudoType, nil
        }

        retTy, err := regexPatternResultType(args[0].AsString())
        if err != nil {
            err = function.NewArgError(0, err)
        }
        return retTy, err
    },
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        if retType == cty.DynamicPseudoType {
            return cty.DynamicVal, nil
        }

        re, err := regexp.Compile(args[0].AsString())
        if err != nil {

            return cty.NilVal, function.NewArgErrorf(0, "error parsing pattern: %s", err)
        }
        str := args[1].AsString()

        captureIdxs := re.FindStringSubmatchIndex(str)
        if captureIdxs == nil {
            return cty.NilVal, fmt.Errorf("pattern did not match any part of the given string")
        }

        return regexPatternResult(re, str, captureIdxs, retType), nil
    },
})
var ReverseFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "str",
            Type:             cty.String,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.String),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        in := []byte(args[0].AsString())
        out := make([]byte, len(in))
        pos := len(out)

        inB := []byte(in)
        for i := 0; i < len(in); {
            d, _, _ := textseg.ScanGraphemeClusters(inB[i:], true)
            cluster := in[i : i+d]
            pos -= len(cluster)
            copy(out[pos:], cluster)
            i += d
        }

        return cty.StringVal(string(out)), nil
    },
})
var SetHasElementFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "set",
            Type:             cty.Set(cty.DynamicPseudoType),
            AllowDynamicType: true,
        },
        {
            Name:             "elem",
            Type:             cty.DynamicPseudoType,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.Bool),
    Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
        return args[0].HasElement(args[1]), nil
    },
})
var SetIntersectionFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "first_set",
            Type:             cty.Set(cty.DynamicPseudoType),
            AllowDynamicType: true,
        },
    },
    VarParam: &function.Parameter{
        Name:             "other_sets",
        Type:             cty.Set(cty.DynamicPseudoType),
        AllowDynamicType: true,
    },
    Type: setOperationReturnType,
    Impl: setOperationImpl(func(s1, s2 cty.ValueSet) cty.ValueSet {
        return s1.Intersection(s2)
    }),
})
var SetSubtractFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "a",
            Type:             cty.Set(cty.DynamicPseudoType),
            AllowDynamicType: true,
        },
        {
            Name:             "b",
            Type:             cty.Set(cty.DynamicPseudoType),
            AllowDynamicType: true,
        },
    },
    Type: setOperationReturnType,
    Impl: setOperationImpl(func(s1, s2 cty.ValueSet) cty.ValueSet {
        return s1.Subtract(s2)
    }),
})
var SetSymmetricDifferenceFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "first_set",
            Type:             cty.Set(cty.DynamicPseudoType),
            AllowDynamicType: true,
        },
    },
    VarParam: &function.Parameter{
        Name:             "other_sets",
        Type:             cty.Set(cty.DynamicPseudoType),
        AllowDynamicType: true,
    },
    Type: setOperationReturnType,
    Impl: setOperationImpl(func(s1, s2 cty.ValueSet) cty.ValueSet {
        return s1.Subtract(s2)
    }),
})
var SetUnionFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "first_set",
            Type:             cty.Set(cty.DynamicPseudoType),
            AllowDynamicType: true,
        },
    },
    VarParam: &function.Parameter{
        Name:             "other_sets",
        Type:             cty.Set(cty.DynamicPseudoType),
        AllowDynamicType: true,
    },
    Type: setOperationReturnType,
    Impl: setOperationImpl(func(s1, s2 cty.ValueSet) cty.ValueSet {
        return s1.Union(s2)
    }),
})
var StrlenFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "str",
            Type:             cty.String,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.Number),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        in := args[0].AsString()
        l := 0

        inB := []byte(in)
        for i := 0; i < len(in); {
            d, _, _ := textseg.ScanGraphemeClusters(inB[i:], true)
            l++
            i += d
        }

        return cty.NumberIntVal(int64(l)), nil
    },
})
var SubstrFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "str",
            Type:             cty.String,
            AllowDynamicType: true,
        },
        {
            Name:             "offset",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
        {
            Name:             "length",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.String),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        in := []byte(args[0].AsString())
        var offset, length int

        var err error
        err = gocty.FromCtyValue(args[1], &offset)
        if err != nil {
            return cty.NilVal, err
        }
        err = gocty.FromCtyValue(args[2], &length)
        if err != nil {
            return cty.NilVal, err
        }

        if offset < 0 {
            totalLenNum, err := Strlen(args[0])
            if err != nil {

                panic("Stdlen returned an error")
            }

            var totalLen int
            err = gocty.FromCtyValue(totalLenNum, &totalLen)
            if err != nil {

                panic("Stdlen returned a non-int number")
            }

            offset += totalLen
        }

        sub := in
        pos := 0
        var i int

        if offset > 0 {
            for i = 0; i < len(sub); {
                d, _, _ := textseg.ScanGraphemeClusters(sub[i:], true)
                i += d
                pos++
                if pos == offset {
                    break
                }
                if i >= len(in) {
                    return cty.StringVal(""), nil
                }
            }

            sub = sub[i:]
        }

        if length < 0 {

            return cty.StringVal(string(sub)), nil
        }

        pos = 0
        for i = 0; i < len(sub); {
            d, _, _ := textseg.ScanGraphemeClusters(sub[i:], true)
            i += d
            pos++
            if pos == length {
                break
            }
        }

        sub = sub[:i]

        return cty.StringVal(string(sub)), nil
    },
})
var SubtractFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "a",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
        {
            Name:             "b",
            Type:             cty.Number,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.Number),
    Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {

        defer func() {
            if r := recover(); r != nil {
                if _, ok := r.(big.ErrNaN); ok {
                    ret = cty.NilVal
                    err = fmt.Errorf("can't subtract infinity from itself")
                } else {

                    panic(r)
                }
            }
        }()
        return args[0].Subtract(args[1]), nil
    },
})
var UpperFunc = function.New(&function.Spec{
    Params: []function.Parameter{
        {
            Name:             "str",
            Type:             cty.String,
            AllowDynamicType: true,
        },
    },
    Type: function.StaticReturnType(cty.String),
    Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
        in := args[0].AsString()
        out := strings.ToUpper(in)
        return cty.StringVal(out), nil
    },
})

func Absolute Uses

func Absolute(num cty.Value) (cty.Value, error)

Absolute returns the magnitude of the given number, without its sign. That is, it turns negative values into positive values.

func Add Uses

func Add(a cty.Value, b cty.Value) (cty.Value, error)

Add returns the sum of the two given numbers.

func And Uses

func And(a, b cty.Value) (cty.Value, error)

And returns true if and only if both of the given boolean values are true.

func BytesLen Uses

func BytesLen(buf cty.Value) (cty.Value, error)

func BytesSlice Uses

func BytesSlice(buf cty.Value, offset cty.Value, length cty.Value) (cty.Value, error)

func BytesVal Uses

func BytesVal(buf []byte) cty.Value

BytesVal creates a new Bytes value from the given buffer, which must be non-nil or this function will panic.

Once a byte slice has been wrapped in a Bytes capsule, its underlying array must be considered immutable.

func CSVDecode Uses

func CSVDecode(str cty.Value) (cty.Value, error)

CSVDecode parses the given CSV (RFC 4180) string and, if it is valid, returns a list of objects representing the rows.

The result is always a list of some object type. The first row of the input is used to determine the object attributes, and subsequent rows determine the values of those attributes.

func Coalesce Uses

func Coalesce(vals ...cty.Value) (cty.Value, error)

Coalesce returns the first of the given arguments that is not null. If all arguments are null, an error is produced.

func Concat Uses

func Concat(seqs ...cty.Value) (cty.Value, error)

Concat takes one or more sequences (lists or tuples) and returns the single sequence that results from concatenating them together in order.

If all of the given sequences are lists of the same element type then the result is a list of that type. Otherwise, the result is a of a tuple type constructed from the given sequence types.

func Divide Uses

func Divide(a cty.Value, b cty.Value) (cty.Value, error)

Divide returns a divided by b, where both a and b are numbers.

func Equal Uses

func Equal(a cty.Value, b cty.Value) (cty.Value, error)

Equal determines whether the two given values are equal, returning a bool value.

func Format Uses

func Format(format cty.Value, vals ...cty.Value) (cty.Value, error)

Format produces a string representation of zero or more values using a format string similar to the "printf" function in C.

It supports the following "verbs":

%%      Literal percent sign, consuming no value
%v      A default formatting of the value based on type, as described below.
%#v     JSON serialization of the value
%t      Converts to boolean and then produces "true" or "false"
%b      Converts to number, requires integer, produces binary representation
%d      Converts to number, requires integer, produces decimal representation
%o      Converts to number, requires integer, produces octal representation
%x      Converts to number, requires integer, produces hexadecimal representation
        with lowercase letters
%X      Like %x but with uppercase letters
%e      Converts to number, produces scientific notation like -1.234456e+78
%E      Like %e but with an uppercase "E" representing the exponent
%f      Converts to number, produces decimal representation with fractional
        part but no exponent, like 123.456
%g      %e for large exponents or %f otherwise
%G      %E for large exponents or %f otherwise
%s      Converts to string and produces the string's characters
%q      Converts to string and produces JSON-quoted string representation,
        like %v.

The default format selections made by %v are:

string  %s
number  %g
bool    %t
other   %#v

Null values produce the literal keyword "null" for %v and %#v, and produce an error otherwise.

Width is specified by an optional decimal number immediately preceding the verb letter. If absent, the width is whatever is necessary to represent the value. Precision is specified after the (optional) width by a period followed by a decimal number. If no period is present, a default precision is used. A period with no following number is invalid. For examples:

%f     default width, default precision
%9f    width 9, default precision
%.2f   default width, precision 2
%9.2f  width 9, precision 2

Width and precision are measured in unicode characters (grapheme clusters).

For most values, width is the minimum number of characters to output, padding the formatted form with spaces if necessary.

For strings, precision limits the length of the input to be formatted (not the size of the output), truncating if necessary.

For numbers, width sets the minimum width of the field and precision sets the number of places after the decimal, if appropriate, except that for %g/%G precision sets the total number of significant digits.

The following additional symbols can be used immediately after the percent introducer as flags:

      (a space) leave a space where the sign would be if number is positive
+     Include a sign for a number even if it is positive (numeric only)
-     Pad with spaces on the left rather than the right
0     Pad with zeros rather than spaces.

Flag characters are ignored for verbs that do not support them.

By default, % sequences consume successive arguments starting with the first. Introducing a [n] sequence immediately before the verb letter, where n is a decimal integer, explicitly chooses a particular value argument by its one-based index. Subsequent calls without an explicit index will then proceed with n+1, n+2, etc.

An error is produced if the format string calls for an impossible conversion or accesses more values than are given. An error is produced also for an unsupported format verb.

func FormatDate Uses

func FormatDate(format cty.Value, timestamp cty.Value) (cty.Value, error)

FormatDate reformats a timestamp given in RFC3339 syntax into another time syntax defined by a given format string.

The format string uses letter mnemonics to represent portions of the timestamp, with repetition signifying length variants of each portion. Single quote characters ' can be used to quote sequences of literal letters that should not be interpreted as formatting mnemonics.

The full set of supported mnemonic sequences is listed below:

YY       Year modulo 100 zero-padded to two digits, like "06".
YYYY     Four (or more) digit year, like "2006".
M        Month number, like "1" for January.
MM       Month number zero-padded to two digits, like "01".
MMM      English month name abbreviated to three letters, like "Jan".
MMMM     English month name unabbreviated, like "January".
D        Day of month number, like "2".
DD       Day of month number zero-padded to two digits, like "02".
EEE      English day of week name abbreviated to three letters, like "Mon".
EEEE     English day of week name unabbreviated, like "Monday".
h        24-hour number, like "2".
hh       24-hour number zero-padded to two digits, like "02".
H        12-hour number, like "2".
HH       12-hour number zero-padded to two digits, like "02".
AA       Hour AM/PM marker in uppercase, like "AM".
aa       Hour AM/PM marker in lowercase, like "am".
m        Minute within hour, like "5".
mm       Minute within hour zero-padded to two digits, like "05".
s        Second within minute, like "9".
ss       Second within minute zero-padded to two digits, like "09".
ZZZZ     Timezone offset with just sign and digit, like "-0800".
ZZZZZ    Timezone offset with colon separating hours and minutes, like "-08:00".
Z        Like ZZZZZ but with a special case "Z" for UTC.
ZZZ      Like ZZZZ but with a special case "UTC" for UTC.

The format syntax is optimized mainly for generating machine-oriented timestamps rather than human-oriented timestamps; the English language portions of the output reflect the use of English names in a number of machine-readable date formatting standards. For presentation to humans, a locale-aware time formatter (not included in this package) is a better choice.

The format syntax is not compatible with that of any other language, but is optimized so that patterns for common standard date formats can be recognized quickly even by a reader unfamiliar with the format syntax.

func FormatList Uses

func FormatList(format cty.Value, vals ...cty.Value) (cty.Value, error)

FormatList applies the same formatting behavior as Format, but accepts a mixture of list and non-list values as arguments. Any list arguments passed must have the same length, which dictates the length of the resulting list.

Any non-list arguments are used repeatedly for each iteration over the list arguments. The list arguments are iterated in order by key, so corresponding items are formatted together.

func GreaterThan Uses

func GreaterThan(a cty.Value, b cty.Value) (cty.Value, error)

GreaterThan returns true if a is less than b.

func GreaterThanOrEqualTo Uses

func GreaterThanOrEqualTo(a cty.Value, b cty.Value) (cty.Value, error)

GreaterThanOrEqualTo returns true if a is less than b.

func HasIndex Uses

func HasIndex(collection cty.Value, key cty.Value) (cty.Value, error)

HasIndex determines whether the given collection can be indexed with the given key.

func Index Uses

func Index(collection cty.Value, key cty.Value) (cty.Value, error)

Index returns an element from the given collection using the given key, or returns an error if there is no element for the given key.

func Int Uses

func Int(num cty.Value) (cty.Value, error)

Int removes the fractional component of the given number returning an integer representing the whole number component, rounding towards zero. For example, -1.5 becomes -1.

If an infinity is passed to Int, an error is returned.

func JSONDecode Uses

func JSONDecode(str cty.Value) (cty.Value, error)

JSONDecode parses the given JSON string and, if it is valid, returns the value it represents.

Note that applying JSONDecode to the result of JSONEncode may not produce an identically-typed result, since JSON encoding is lossy for cty Types. The resulting value will consist only of primitive types, object types, and tuple types.

func JSONEncode Uses

func JSONEncode(val cty.Value) (cty.Value, error)

JSONEncode returns a JSON serialization of the given value.

func Length Uses

func Length(collection cty.Value) (cty.Value, error)

Length returns the number of elements in the given collection.

func LessThan Uses

func LessThan(a cty.Value, b cty.Value) (cty.Value, error)

LessThan returns true if a is less than b.

func LessThanOrEqualTo Uses

func LessThanOrEqualTo(a cty.Value, b cty.Value) (cty.Value, error)

LessThanOrEqualTo returns true if a is less than b.

func Lower Uses

func Lower(str cty.Value) (cty.Value, error)

Lower is a Function that converts a given string to lowercase.

func Max Uses

func Max(numbers ...cty.Value) (cty.Value, error)

Max returns the maximum number from the given numbers.

func Min Uses

func Min(numbers ...cty.Value) (cty.Value, error)

Min returns the minimum number from the given numbers.

func Modulo Uses

func Modulo(a cty.Value, b cty.Value) (cty.Value, error)

Modulo returns the remainder of a divided by b under integer division, where both a and b are numbers.

func Multiply Uses

func Multiply(a cty.Value, b cty.Value) (cty.Value, error)

Multiply returns the product of the two given numbers.

func Negate Uses

func Negate(num cty.Value) (cty.Value, error)

Negate returns the given number multipled by -1.

func Not Uses

func Not(num cty.Value) (cty.Value, error)

Not returns the logical complement of the given boolean value.

func NotEqual Uses

func NotEqual(a cty.Value, b cty.Value) (cty.Value, error)

NotEqual is the opposite of Equal.

func Or Uses

func Or(a, b cty.Value) (cty.Value, error)

Or returns true if either of the given boolean values are true.

func Range Uses

func Range(params ...cty.Value) (cty.Value, error)

Range creates a list of numbers by starting from the given starting value, then adding the given step value until the result is greater than or equal to the given stopping value. Each intermediate result becomes an element in the resulting list.

When all three parameters are set, the order is (start, end, step). If only two parameters are set, they are the start and end respectively and step defaults to 1. If only one argument is set, it gives the end value with start defaulting to 0 and step defaulting to 1.

Because the resulting list must be fully buffered in memory, there is an artificial cap of 1024 elements, after which this function will return an error to avoid consuming unbounded amounts of memory. The Range function is primarily intended for creating small lists of indices to iterate over, so there should be no reason to generate huge lists with it.

func Regex Uses

func Regex(pattern, str cty.Value) (cty.Value, error)

Regex is a function that extracts one or more substrings from a given string by applying a regular expression pattern, describing the first match.

The return type depends on the composition of the capture groups (if any) in the pattern:

- If there are no capture groups at all, the result is a single string
  representing the entire matched pattern.
- If all of the capture groups are named, the result is an object whose
  keys are the named groups and whose values are their sub-matches, or
  null if a particular sub-group was inside another group that didn't
  match.
- If none of the capture groups are named, the result is a tuple whose
  elements are the sub-groups in order and whose values are their
  sub-matches, or null if a particular sub-group was inside another group
  that didn't match.
- It is invalid to use both named and un-named capture groups together in
  the same pattern.

If the pattern doesn't match, this function returns an error. To test for a match, call RegexAll and check if the length of the result is greater than zero.

func RegexAll Uses

func RegexAll(pattern, str cty.Value) (cty.Value, error)

RegexAll is similar to Regex but it finds all of the non-overlapping matches in the given string and returns a list of them.

The result type is always a list, whose element type is deduced from the pattern in the same way as the return type for Regex is decided.

If the pattern doesn't match at all, this function returns an empty list.

func Reverse Uses

func Reverse(str cty.Value) (cty.Value, error)

Reverse is a Function that reverses the order of the characters in the given string.

As usual, "character" for the sake of this function is a grapheme cluster, so combining diacritics (for example) will be considered together as a single character.

func SetHasElement Uses

func SetHasElement(set cty.Value, elem cty.Value) (cty.Value, error)

SetHasElement determines whether the given set contains the given value as an element.

func SetIntersection Uses

func SetIntersection(sets ...cty.Value) (cty.Value, error)

Intersection returns a new set containing the elements that exist in all of the given sets, which must have element types that can all be converted to some common type using the standard type unification rules. If conversion is not possible, an error is returned.

The intersection operation is performed after type conversion, which may result in some previously-distinct values being conflated.

At least one set must be provided.

func SetSubtract Uses

func SetSubtract(a, b cty.Value) (cty.Value, error)

SetSubtract returns a new set containing the elements from the first set that are not present in the second set. The sets must have element types that can both be converted to some common type using the standard type unification rules. If conversion is not possible, an error is returned.

The subtract operation is performed after type conversion, which may result in some previously-distinct values being conflated.

func SetSymmetricDifference Uses

func SetSymmetricDifference(sets ...cty.Value) (cty.Value, error)

SetSymmetricDifference returns a new set containing elements that appear in any of the given sets but not multiple. The sets must have element types that can all be converted to some common type using the standard type unification rules. If conversion is not possible, an error is returned.

The difference operation is performed after type conversion, which may result in some previously-distinct values being conflated.

func SetUnion Uses

func SetUnion(sets ...cty.Value) (cty.Value, error)

SetUnion returns a new set containing all of the elements from the given sets, which must have element types that can all be converted to some common type using the standard type unification rules. If conversion is not possible, an error is returned.

The union operation is performed after type conversion, which may result in some previously-distinct values being conflated.

At least one set must be provided.

func Strlen Uses

func Strlen(str cty.Value) (cty.Value, error)

Strlen is a Function that returns the length of the given string in characters.

As usual, "character" for the sake of this function is a grapheme cluster, so combining diacritics (for example) will be considered together as a single character.

func Substr Uses

func Substr(str cty.Value, offset cty.Value, length cty.Value) (cty.Value, error)

Substr is a Function that extracts a sequence of characters from another string and creates a new string.

As usual, "character" for the sake of this function is a grapheme cluster, so combining diacritics (for example) will be considered together as a single character.

The "offset" index may be negative, in which case it is relative to the end of the given string.

The "length" may be -1, in which case the remainder of the string after the given offset will be returned.

func Subtract Uses

func Subtract(a cty.Value, b cty.Value) (cty.Value, error)

Subtract returns the difference between the two given numbers.

func Upper Uses

func Upper(str cty.Value) (cty.Value, error)

Upper is a Function that converts a given string to uppercase.

Package stdlib imports 18 packages (graph) and is imported by 37 packages. Updated 2019-09-12. Refresh now. Tools for package owners.