2021-09-07 17:36:50 +03:00
|
|
|
package rui
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sort"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Properties interface of properties map
|
|
|
|
type Properties interface {
|
|
|
|
// Get returns a value of the property with name defined by the argument.
|
|
|
|
// The type of return value depends on the property. If the property is not set then nil is returned.
|
2024-11-13 12:56:39 +03:00
|
|
|
Get(tag PropertyName) any
|
|
|
|
getRaw(tag PropertyName) any
|
2024-04-23 19:34:36 +03:00
|
|
|
|
2021-09-07 17:36:50 +03:00
|
|
|
// Set sets the value (second argument) of the property with name defined by the first argument.
|
|
|
|
// Return "true" if the value has been set, in the opposite case "false" are returned and
|
|
|
|
// a description of the error is written to the log
|
2024-11-13 12:56:39 +03:00
|
|
|
Set(tag PropertyName, value any) bool
|
|
|
|
setRaw(tag PropertyName, value any)
|
2024-04-23 19:34:36 +03:00
|
|
|
|
2021-09-07 17:36:50 +03:00
|
|
|
// Remove removes the property with name defined by the argument
|
2024-11-13 12:56:39 +03:00
|
|
|
Remove(tag PropertyName)
|
2024-04-23 19:34:36 +03:00
|
|
|
|
2021-09-07 17:36:50 +03:00
|
|
|
// Clear removes all properties
|
|
|
|
Clear()
|
2024-04-23 19:34:36 +03:00
|
|
|
|
2021-09-07 17:36:50 +03:00
|
|
|
// AllTags returns an array of the set properties
|
2024-11-13 12:56:39 +03:00
|
|
|
AllTags() []PropertyName
|
|
|
|
|
|
|
|
empty() bool
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
type propertyList struct {
|
2024-11-13 12:56:39 +03:00
|
|
|
properties map[PropertyName]any
|
|
|
|
normalize func(PropertyName) PropertyName
|
|
|
|
//getFunc func(PropertyName) any
|
|
|
|
//set func(Properties, PropertyName, any) []PropertyName
|
|
|
|
//remove func(Properties, PropertyName) []PropertyName
|
|
|
|
}
|
|
|
|
|
|
|
|
type dataProperty struct {
|
|
|
|
propertyList
|
|
|
|
supportedProperties []PropertyName
|
|
|
|
get func(Properties, PropertyName) any
|
|
|
|
set func(Properties, PropertyName, any) []PropertyName
|
|
|
|
remove func(Properties, PropertyName) []PropertyName
|
|
|
|
}
|
|
|
|
|
|
|
|
func defaultNormalize(tag PropertyName) PropertyName {
|
|
|
|
return PropertyName(strings.ToLower(strings.Trim(string(tag), " \t")))
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func (properties *propertyList) init() {
|
2024-11-13 12:56:39 +03:00
|
|
|
properties.properties = map[PropertyName]any{}
|
|
|
|
properties.normalize = defaultNormalize
|
|
|
|
//properties.getFunc = properties.getRaw
|
|
|
|
//properties.set = propertiesSet
|
|
|
|
//properties.remove = propertiesRemove
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
|
2024-11-13 12:56:39 +03:00
|
|
|
func (properties *propertyList) empty() bool {
|
|
|
|
return len(properties.properties) == 0
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
|
2024-11-13 12:56:39 +03:00
|
|
|
func (properties *propertyList) getRaw(tag PropertyName) any {
|
2021-09-07 17:36:50 +03:00
|
|
|
if value, ok := properties.properties[tag]; ok {
|
|
|
|
return value
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-11-13 12:56:39 +03:00
|
|
|
func (properties *propertyList) setRaw(tag PropertyName, value any) {
|
|
|
|
if value == nil {
|
|
|
|
delete(properties.properties, tag)
|
|
|
|
} else {
|
|
|
|
properties.properties[tag] = value
|
|
|
|
}
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
|
2024-11-13 12:56:39 +03:00
|
|
|
/*
|
|
|
|
func (properties *propertyList) Remove(tag PropertyName) {
|
|
|
|
properties.remove(properties, properties.normalize(tag))
|
|
|
|
}
|
|
|
|
*/
|
2021-09-07 17:36:50 +03:00
|
|
|
func (properties *propertyList) Clear() {
|
2024-11-13 12:56:39 +03:00
|
|
|
properties.properties = map[PropertyName]any{}
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
|
2024-11-13 12:56:39 +03:00
|
|
|
func (properties *propertyList) AllTags() []PropertyName {
|
|
|
|
tags := make([]PropertyName, 0, len(properties.properties))
|
|
|
|
for tag := range properties.properties {
|
|
|
|
tags = append(tags, tag)
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
2024-11-13 12:56:39 +03:00
|
|
|
sort.Slice(tags, func(i, j int) bool {
|
|
|
|
return tags[i] < tags[j]
|
|
|
|
})
|
2021-09-07 17:36:50 +03:00
|
|
|
return tags
|
|
|
|
}
|
|
|
|
|
2024-04-22 19:14:58 +03:00
|
|
|
func (properties *propertyList) writeToBuffer(buffer *strings.Builder,
|
2024-11-13 12:56:39 +03:00
|
|
|
indent string, objectTag string, tags []PropertyName) {
|
2024-04-22 19:14:58 +03:00
|
|
|
|
|
|
|
buffer.WriteString(objectTag)
|
|
|
|
buffer.WriteString(" {\n")
|
|
|
|
|
|
|
|
indent2 := indent + "\t"
|
|
|
|
|
|
|
|
for _, tag := range tags {
|
|
|
|
if value, ok := properties.properties[tag]; ok {
|
|
|
|
buffer.WriteString(indent2)
|
2024-11-13 12:56:39 +03:00
|
|
|
buffer.WriteString(string(tag))
|
2024-04-22 19:14:58 +03:00
|
|
|
buffer.WriteString(" = ")
|
|
|
|
writePropertyValue(buffer, tag, value, indent2)
|
|
|
|
buffer.WriteString(",\n")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
buffer.WriteString(indent)
|
|
|
|
buffer.WriteString("}")
|
|
|
|
}
|
|
|
|
|
2021-09-07 17:36:50 +03:00
|
|
|
func parseProperties(properties Properties, object DataObject) {
|
|
|
|
count := object.PropertyCount()
|
|
|
|
for i := 0; i < count; i++ {
|
|
|
|
if node := object.Property(i); node != nil {
|
|
|
|
switch node.Type() {
|
|
|
|
case TextNode:
|
2024-11-13 12:56:39 +03:00
|
|
|
properties.Set(PropertyName(node.Tag()), node.Text())
|
2021-09-07 17:36:50 +03:00
|
|
|
|
|
|
|
case ObjectNode:
|
2024-11-13 12:56:39 +03:00
|
|
|
properties.Set(PropertyName(node.Tag()), node.Object())
|
2021-09-07 17:36:50 +03:00
|
|
|
|
|
|
|
case ArrayNode:
|
2024-11-13 12:56:39 +03:00
|
|
|
properties.Set(PropertyName(node.Tag()), node.ArrayElements())
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-11-13 12:56:39 +03:00
|
|
|
|
|
|
|
func propertiesGet(properties Properties, tag PropertyName) any {
|
|
|
|
return properties.getRaw(tag)
|
|
|
|
}
|
|
|
|
|
|
|
|
func propertiesRemove(properties Properties, tag PropertyName) []PropertyName {
|
|
|
|
if properties.getRaw(tag) == nil {
|
|
|
|
return []PropertyName{}
|
|
|
|
}
|
|
|
|
properties.setRaw(tag, nil)
|
|
|
|
return []PropertyName{tag}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (data *dataProperty) init() {
|
|
|
|
data.propertyList.init()
|
|
|
|
data.get = propertiesGet
|
|
|
|
data.set = propertiesSet
|
|
|
|
data.remove = propertiesRemove
|
|
|
|
}
|
|
|
|
|
|
|
|
func (data *dataProperty) Get(tag PropertyName) any {
|
|
|
|
return propertiesGet(data, data.normalize(tag))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (data *dataProperty) Remove(tag PropertyName) {
|
|
|
|
data.remove(data, data.normalize(tag))
|
|
|
|
}
|