Select Git revision
config.go 9.18 KiB
package setup
import (
"errors"
"io/fs"
"git.perx.ru/perxis/perxis-go"
"git.perx.ru/perxis/perxis-go/pkg/clients"
"git.perx.ru/perxis/perxis-go/pkg/collections"
"git.perx.ru/perxis/perxis-go/pkg/items"
"git.perx.ru/perxis/perxis-go/pkg/roles"
"github.com/hashicorp/go-multierror"
)
type Config struct {
Roles []RoleConfig
Clients []ClientConfig
Collections []CollectionConfig
Items []ItemConfig
}
func NewConfig() *Config {
return &Config{}
}
// Load загружает Config из файловой системы
// Файлы должны быть расположены в директории со следующей структурой:
// - collections/ - директория с файлами конфигурации коллекций
// - clients/ - директория с файлами конфигурации клиентов
// - items/ - директория с файлами конфигурации элементов
// - roles/ - директория с файлами конфигурации ролей
func (cfg *Config) Load(fsys fs.FS) (*Config, error) {
if subFS, err := fs.Sub(fsys, "collections"); err == nil {
if _, err = cfg.LoadCollections(subFS); err != nil && !errors.Is(err, fs.ErrNotExist) {
return nil, err
}
}
if subFS, err := fs.Sub(fsys, "items"); err == nil {
if _, err = cfg.LoadItems(subFS); err != nil && !errors.Is(err, fs.ErrNotExist) {
return nil, err
}
}
if subFS, err := fs.Sub(fsys, "roles"); err == nil {
if _, err = cfg.LoadRoles(subFS); err != nil && !errors.Is(err, fs.ErrNotExist) {
return nil, err
}
}
if subFS, err := fs.Sub(fsys, "clients"); err == nil {
if _, err = cfg.LoadClients(subFS); err != nil && !errors.Is(err, fs.ErrNotExist) {
return nil, err
}
}
return cfg, nil
}
func (cfg *Config) MustLoad(fsys fs.FS) *Config {
c, err := cfg.Load(fsys)
if err != nil {
panic(err)
}
return c
}
func (cfg *Config) WithCollectionOptions(filter func(c *collections.Collection) bool, opts ...CollectionsOption) *Config {
for i, c := range cfg.Collections {
if filter(c.collection) {
for _, o := range opts {
o(&cfg.Collections[i])
}
}
}
return cfg
}
func (cfg *Config) WithItemsOptions(filter func(c *items.Item) bool, opts ...ItemsOption) *Config {
for i, c := range cfg.Items {
if filter(c.item) {
for _, o := range opts {
o(&cfg.Items[i])
}
}
}
return cfg
}
func (cfg *Config) WithRolesOptions(filter func(c *roles.Role) bool, opts ...RolesOption) *Config {
for i, r := range cfg.Roles {
if filter(r.role) {
for _, o := range opts {
o(&cfg.Roles[i])
}
}
}
return cfg
}
func (cfg *Config) WithClientsOptions(filter func(c *clients.Client) bool, opts ...ClientsOption) *Config {
for i, c := range cfg.Clients {
if filter(c.client) {
for _, o := range opts {
o(&cfg.Clients[i])
}
}
}
return cfg
}
// LoadItems загружает элементы из указанной файловой системы
func (cfg *Config) LoadClients(fsys fs.FS, opt ...ClientsOption) (*Config, error) {
assets := perxis.NewAssets[*clients.Client]()
cls, err := assets.FromFS(fsys)
if err != nil {
return nil, err
}
return cfg.AddClients(cls, opt...), nil
}
func (cfg *Config) MustLoadClients(fsys fs.FS, opt ...ClientsOption) *Config {
c, err := cfg.LoadClients(fsys, opt...)
if err != nil {
panic(err)
}
return c
}
// AddClients добавляет требования к настройке приложений в пространстве
func (cfg *Config) AddClients(clients []*clients.Client, opt ...ClientsOption) *Config {
for _, client := range clients {
cfg.AddClient(client, opt...)
}
return cfg
}
// AddClient добавляет требования к настройке приложений в пространстве
func (c *Config) AddClient(client *clients.Client, opt ...ClientsOption) *Config {
c.Clients = append(c.Clients, NewClientConfig(client, opt...))
return c
}
// LoadItems загружает элементы из указанной файловой системы
func (cfg *Config) LoadRoles(fsys fs.FS, opt ...RolesOption) (*Config, error) {
assets := perxis.NewAssets[*roles.Role]()
rls, err := assets.FromFS(fsys)
if err != nil {
return nil, err
}
return cfg.AddRoles(rls, opt...), nil
}
func (cfg *Config) MustLoadRoles(fsys fs.FS, opt ...RolesOption) *Config {
c, err := cfg.LoadRoles(fsys, opt...)
if err != nil {
panic(err)
}
return c
}
// AddRoles добавляет требования к настройке ролей в пространстве
func (cfg *Config) AddRoles(roles []*roles.Role, opt ...RolesOption) *Config {
for _, role := range roles {
cfg.AddRole(role, opt...)
}
return cfg
}
// AddRole добавляет требования к настройке ролей в пространстве
func (cfg *Config) AddRole(role *roles.Role, opt ...RolesOption) *Config {
cfg.Roles = append(cfg.Roles, NewRoleConfig(role, opt...))
return cfg
}
// AddCollections добавляет требования к настройке коллекций в пространстве
func (cfg *Config) AddCollections(collections []*collections.Collection, opt ...CollectionsOption) (*Config, error) {
var errs *multierror.Error
for _, col := range collections {
if _, err := cfg.AddCollection(col, opt...); err != nil {
errs = multierror.Append(errs, err)
}
}
return cfg, errs.ErrorOrNil()
}
// AddCollection добавляет требование к настройке коллекции в пространстве
func (cfg *Config) AddCollection(collection *collections.Collection, opt ...CollectionsOption) (*Config, error) {
config, err := NewCollectionConfig(collection, opt...)
if err != nil {
return nil, err
}
cfg.Collections = append(cfg.Collections, config)
return cfg, nil
}
// MustAddCollection добавляет требование к настройке коллекции в пространстве
func (cfg *Config) MustAddCollection(collection *collections.Collection, opt ...CollectionsOption) *Config {
config, err := NewCollectionConfig(collection, opt...)
if err != nil {
panic(err)
}
cfg.Collections = append(cfg.Collections, config)
return cfg
}
// LoadCollections загружает коллекции из указанной файловой системы
func (cfg *Config) LoadCollections(fsys fs.FS, opt ...CollectionsOption) (*Config, error) {
colls, err := collections.FromFS(fsys)
if err != nil {
return nil, err
}
return cfg.AddCollections(colls, opt...)
}
func (cfg *Config) MustLoadCollections(fsys fs.FS, opt ...CollectionsOption) *Config {
c, err := cfg.LoadCollections(fsys, opt...)
if err != nil {
panic(err)
}
return c
}
// GetCollection возвращает коллекцию по идентификатору
func (cfg *Config) GetCollection(id string) *collections.Collection {
for _, c := range cfg.Collections {
if c.collection.ID == id {
return c.collection
}
}
return nil
}
// GetCollection возвращает коллекцию по идентификатору
func (cfg *Config) GetAllCollections() []*collections.Collection {
res := make([]*collections.Collection, 0, len(cfg.Collections))
for _, c := range cfg.Collections {
res = append(res, c.collection)
}
return res
}
// GetCollectionConfig возвращает конфигурацию коллекции по идентификатору
func (cfg *Config) GetCollectionConfig(id string) *CollectionConfig {
for _, c := range cfg.Collections {
if c.collection.ID == id {
return &c
}
}
return nil
}
// LoadItems загружает элементы из указанной файловой системы
func (cfg *Config) LoadItems(fsys fs.FS, opt ...ItemsOption) (*Config, error) {
assets := perxis.NewAssets[*items.Item]()
itms, err := assets.FromFS(fsys)
if err != nil {
return nil, err
}
return cfg.AddItems(itms, append(opt, DecodeItem())...), nil
}
func (cfg *Config) MustLoadItems(fsys fs.FS, opt ...ItemsOption) *Config {
cfg, err := cfg.LoadItems(fsys, opt...)
if err != nil {
panic(err)
}
return cfg
}
// AddItems добавляет требования к настройке элементов в пространстве
func (cfg *Config) AddItems(items []*items.Item, opt ...ItemsOption) *Config {
for _, item := range items {
cfg.AddItem(item, opt...)
}
return cfg
}
// AddItem добавляет требования к настройке элементов в пространстве
func (cfg *Config) AddItem(item *items.Item, opt ...ItemsOption) *Config {
cfg.Items = append(cfg.Items, NewItemConfig(item, opt...))
return cfg
}
// GetItems возвращает элементы для указанной коллекции
func (cfg *Config) GetItems(collectionId string) []*items.Item {
var items []*items.Item
for _, i := range cfg.Items {
if i.item.CollectionID == collectionId {
items = append(items, i.item)
}
}
return items
}
// GetItem возвращает элемент для указанной коллекции и идентификатора
func (cfg *Config) GetItem(collectionId, itemId string) *items.Item {
for _, i := range cfg.Items {
if i.item.CollectionID == collectionId && i.item.ID == itemId {
return i.item
}
}
return nil
}