2022-07-10 00:48:38 +01:00
|
|
|
// Package asld handles JSON-LD for asflab
|
|
|
|
//
|
|
|
|
// This will not go well
|
|
|
|
package asld
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2022-07-10 21:23:00 +01:00
|
|
|
tagName = "asld"
|
|
|
|
omitEmpty = "omitempty"
|
|
|
|
collapsible = "collapsible"
|
|
|
|
nullToken = "null"
|
2022-07-10 00:48:38 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2022-07-10 21:23:00 +01:00
|
|
|
ErrNoMatching = errors.New("could not find matching")
|
|
|
|
ErrSyntaxError = errors.New("syntax error")
|
|
|
|
ErrEntryWithoutValue = errors.New("entry without value")
|
|
|
|
ErrMapNotStringIndexed = errors.New("map is not string indexed")
|
2022-07-10 00:48:38 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// assigned by init
|
|
|
|
var (
|
2022-07-10 21:23:00 +01:00
|
|
|
stoppableByByte map[byte]SymbolInfo
|
|
|
|
stoppableRaw []byte
|
|
|
|
iriPrefixes [][]byte
|
|
|
|
openSymbols []SymbolInfo
|
|
|
|
openRaw []byte
|
|
|
|
null []byte
|
2022-07-10 00:48:38 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
2022-07-10 21:23:00 +01:00
|
|
|
stoppableByByte = map[byte]SymbolInfo{}
|
|
|
|
for index, sym := range stoppable {
|
|
|
|
stoppable[index].enum = symbol(index)
|
|
|
|
stoppableByByte[sym.self] = sym
|
2022-07-10 00:48:38 +01:00
|
|
|
}
|
2022-07-10 21:23:00 +01:00
|
|
|
stoppableRaw = make([]byte, len(stoppable))
|
|
|
|
for index, symbol := range stoppable {
|
|
|
|
stoppableRaw[index] = symbol.self
|
2022-07-10 00:48:38 +01:00
|
|
|
}
|
|
|
|
iriPrefixesStrings := []string{
|
|
|
|
// Currently only doing https
|
|
|
|
"https://",
|
|
|
|
}
|
|
|
|
iriPrefixes = make([][]byte, len(iriPrefixesStrings))
|
|
|
|
for index, prefix := range iriPrefixesStrings {
|
|
|
|
iriPrefixes[index] = []byte(prefix)
|
|
|
|
}
|
2022-07-10 21:23:00 +01:00
|
|
|
openSymbolEnums := []symbol{
|
2022-07-10 00:48:38 +01:00
|
|
|
symbolOpenParen, symbolOpenArray, symbolString,
|
|
|
|
}
|
2022-07-10 21:23:00 +01:00
|
|
|
openSymbols = make([]SymbolInfo, len(openSymbolEnums))
|
2022-07-10 00:48:38 +01:00
|
|
|
for index, enum := range openSymbolEnums {
|
2022-07-10 21:23:00 +01:00
|
|
|
openSymbols[index] = stoppable[enum]
|
2022-07-10 00:48:38 +01:00
|
|
|
}
|
2022-07-10 21:23:00 +01:00
|
|
|
openRaw = _map(openSymbols, func(s SymbolInfo) byte {
|
2022-07-10 00:48:38 +01:00
|
|
|
return s.self
|
|
|
|
})
|
2022-07-10 21:23:00 +01:00
|
|
|
null = []byte(nullToken)
|
2022-07-10 00:48:38 +01:00
|
|
|
}
|
|
|
|
|
2022-07-10 21:23:00 +01:00
|
|
|
type SymbolInfo struct {
|
2022-07-10 00:48:38 +01:00
|
|
|
self byte
|
|
|
|
closer byte
|
2022-07-10 21:23:00 +01:00
|
|
|
enum symbol
|
2022-07-10 00:48:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func in[T comparable](this []T, has T) bool {
|
|
|
|
for _, elem := range this {
|
|
|
|
if elem == has {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2022-07-10 21:23:00 +01:00
|
|
|
func firstIn[T comparable](this []T, has T) (T, bool) {
|
|
|
|
for _, elem := range this {
|
|
|
|
if elem == has {
|
|
|
|
return elem, true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return has, false
|
|
|
|
}
|
|
|
|
|
2022-07-10 00:48:38 +01:00
|
|
|
func _map[T any, V any](v []T, f func(T) V) []V {
|
|
|
|
output := make([]V, len(v))
|
|
|
|
for index, elem := range v {
|
|
|
|
output[index] = f(elem)
|
|
|
|
}
|
|
|
|
return output
|
|
|
|
}
|
|
|
|
|
|
|
|
func isIRI(v []byte) bool {
|
|
|
|
for _, prefix := range iriPrefixes {
|
|
|
|
if bytes.Equal(v, prefix) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|