Custom Types
Do you know how to "slice" a message
Golang has built-in primitive data types (int, string, bool, float64, ...) and built-in composite data types (array, slice, map, ...) which also are used in custom commands.
YAGPDB's templating "engine" has currently two user-defined, custom data types - templates.Slice and templates.SDict. There are other custom data types used like discordgo.Timestamp, but these are outside of the main code of YAGPDB, so not explained here further. Type time.Time is covered in it's own section.
Custom Types section discusses functions that initialize values carrying those templates.Slice (abridged to cslice), templates.SDict (abridged to sdict) types and their methods. Both types handle type interface{} element. It's called an empty interface which allows a value to be of any type. So any argument of any type given is handled. (In "custom commands"-wise mainly primitive data types, but slices as well.)
templates.Slice
[]interface{}
- This is a custom composite data type of a slice (similar to array) having interface{} type as its value and can be initialized using cslice
function. Retrieving specific element inside templates.Slice is by indexing its position number.
Function
Description
cslice value1 value2 ...
Function creates a slice of type templates.Slice that can be used elsewhere (as an argument for cembed
and sdict
for example).
Example: cslice 1 "2" (dict "three" 3) 4.5
returns [1 2 map[three:3] 4.5]
, having length of 4 and index positions from 0 to 3. Notice that thanks to type interface{} value, templates.Slice elements' inherent type does not change.
Method
Description
.Append arg
Creates a new cslice having given argument appended fully by its type to current value. Has max size of 10 000 length.
.AppendSlice arg
Creates a new cslice from argument of type slice appended/joined with current value. Has max size of 10 000 length.
.Set int value
Changes/sets given int argument as index position of current cslice to new value. Note that .Set can only set indexes which already exist in the slice.
.StringSlice strict-flag
Compares slice contents - are they of type string, based on the strict-flag which is boolean and is by default false. Under these circumstances if the element is a string then those elements will be included as a part of the []string slice and rest simply ignored. Also time.Time elements - their default string notation will be included. If none are string an empty []string slice is returned.
If strict-flag is set to true it will return a []string only if all elements are pure string, else <no value>
is returned.
Example:
To demonstrate .StringSlice
{{(cslice currentTime.Month 42 "YAPGDB").StringSlice}}
will return a slice[February YAGPDB]
. If the flag would have been set to true - {{...).StringSlice true}}, all elements in that slice were not strings and<no value>
is returned.
General example:
templates.SDict
map[string]interface{}
- This is a custom composite data type of a map having string type as its key and interface{} type as that key's value and can be initialized using sdict
function. A map is key-value store. This means you store value and you access that value by a key. Map is an unordered list and the number of parameters to form key-value pairs must be even. Retrieving specific element inside templates.Sdict is by indexing its key.
Function
Description
sdict "key1" value1 "key2" value2 ...
Like dict function, creating a templates.SDict type map, key must be of type string. Can be used for example in cembed
. If only one argument is passed to sdict
function having type map[string]interface{}; for example .ExecData and data retrieved from database can be of such type if sdict
was used, it is converted to a new sdict.
Example: sdict "one" 1 "two" 2 "three" (cslice 3 4) "five" 5.5
returns unordered map[five:5.5 one:1 three:[3 4] two:2]
, having length of four and index positions are its keys. Notice that thanks to type interface{} value, templates.SDict elements' inherent type does not change.
Method
Description
.Del "key"
Deletes given key from sdict.
.Get "key"
Retrieves given key from sdict.
.Set "key" value
Changes/sets given key to a new value or creates new one, if no such key exists in sdict.
sdict
inside asdict
.
Since both templates.SDict (sdict
) and templates.Slice (cslice
) are custom composite data types, this type information is lost while saving to a database or passing as data to scheduled execCC
or scheduleUniqueCC
(which internally involves saving to database). Thus, they are converted to their underlying data types map[string]interface{} and []interface{} respectively.
They can be converted back to templates.SDict and templates.Slice as follows :
For sdict
-
{{$sdict := sdict "a" 1 "b" "two"}}
{{dbSet 0 "example" $sdict}}
{{$map := (dbGet 0 "example").Value}}
{{$sdict_converted := sdict $map}}
For cslice
-
{{$cslice := cslice 1 "two" 3.0}}
{{dbSet 0 "example" $cslice}}
{{$slice := (dbGet 0 "example").Value}}
{{$cslice_converted := (cslice).AppendSlice $slice}}
The above examples use some database specific functions which are explained here.
Last updated
Was this helpful?