config

package
v0.0.0-...-d4f462a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 4, 2015 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Package config handles the scopes and the configuration via consul, etc or simple files.

Elements

The three elements Section, Group and Field represents front end configuration fields and more important default values and their backend/source models (loading and saving).

Those three elements represents the PackageConfiguration variable which can be found in any package.

Your app which includes the csfw must merge all "PackageConfiguration"s into a single slice. You should submit all default values (interface config.Sectioner) to the config.Manager.ApplyDefaults() function.

The models included in PackageConfiguration will be later used when handling the values for each configuration field.

The JSON enconding of the three elements Section, Group and Field are intended to use on the backend REST API and for debugging and testing. Only used in non performance critical parts.

Scope Values

To get a value from the configuration manager via any Get* method you have to set up the arguments. At least a config.Path() is needed. If you need a config value from another scope (store or website) you must also supply a Scope*() value. Without the scope the default value will be returned. The order of the arguments doesn't matter.

val := config.Manager.GetString(config.Path("path/to/setting"))

Above code returns the default value for path/to/setting key.

Can also be rewritten without using slashes:

val := config.Manager.GetString(config.Path("path", "to", "setting"))

Returning a website scope based value:

w := store.Manager.Website()
val := config.Manager.GetString(config.Path("path/to/setting"), config.Scope(config.ScopeWebsiteID, w))

can be rewritten as:

w := store.Manager.Website()
val := config.Manager.GetString(config.Path("path/to/setting"), config.ScopeWebsite(w))

The code returns the value for a specific website scope. If the value has not been found then the default value will be returned.

Returning a store scope based value:

w := store.Manager.Website()
val := config.Manager.GetString(config.Path("path/to/setting"), config.Scope(config.ScopeStoreID, w))

can be rewritten as:

w := store.Manager.Website()
val := config.Manager.GetString(config.Path("path/to/setting"), config.ScopeStore(w))

The code returns the value for a specific store scope. If the value has not been found then the default value will be returned.

Mixing Store and Website scope in calling of any Write/Get*() function will return that value which scope will be added at last to the OptionFunc slice.

Scope Writes

Storing config values happens via the Write() function. The order of the arguments doesn't matter.

Default Scope:

Write(config.Path("currency", "option", "base"), config.Value("USD"))

Website Scope:

Write(config.Path("currency", "option", "base"), config.Value("EUR"), config.ScopeWebsite(w))

Store Scope:

Write(config.Path("currency", "option", "base"), config.ValueReader(resp.Body), config.ScopeStore(s))

An io.Reader is provided with automatic Close() calling.

Index

Constants

View Source
const (
	LeftDelim  = "{{"
	RightDelim = "}}"
)

LeftDelim and RightDelim are used withing the core_config_data.value field to allow the replacement of the placeholder in exchange with the current value.

View Source
const (
	PathCSBaseURL = "web/corestore/base_url"
	CSBaseURL     = "http://localhost:9500/"
)

PathCSBaseURL main CoreStore base URL, used if no configuration on a store level can be found.

View Source
const (
	// StringScopeDefault defines the global scope. Stored in table core_config_data.scope.
	ScopeRangeDefault = "default"
	// StringScopeWebsites defines the website scope which has default as parent and stores as child.
	//  Stored in table core_config_data.scope.
	ScopeRangeWebsites = "websites"
	// StringScopeStores defines the store scope which has default and websites as parent.
	//  Stored in table core_config_data.scope.
	ScopeRangeStores = "stores"
)
View Source
const PS = "/"

PS path separator used in the database table core_config_data and in config.Manager

Variables

View Source
var ErrFieldNotFound = errors.New("Field not found")

ErrFieldNotFound error when a field cannot be found.

View Source
var ErrGroupNotFound = errors.New("Group not found")

ErrGroupNotFound error when a group cannot be found

View Source
var ErrSectionNotFound = errors.New("Section not found")

ErrSectionNotFound error when a section cannot be found.

ScopePermAll convenient helper variable contains all scope permission levels

Functions

func MockBool

func MockBool(f func(path string) bool) mockOptionFunc

MockBool returns a function which can be used in the NewMockReader(). Your function returns a bool value from a given path.

func MockFloat64

func MockFloat64(f func(path string) float64) mockOptionFunc

MockFloat64 returns a function which can be used in the NewMockReader(). Your function returns a float64 value from a given path.

func MockInt

func MockInt(f func(path string) int) mockOptionFunc

MockInt returns a function which can be used in the NewMockReader(). Your function returns an int value from a given path.

func MockPathScopeDefault

func MockPathScopeDefault(id int64, path string) string

MockPathScopeDefault creates for testing a fully qualified path for the default scope from a Scope ID and a path string (a/b/c)

func MockPathScopeStore

func MockPathScopeStore(id int64, path string) string

MockPathScopeStore creates for testing a fully qualified path for the store scope from a Scope ID and a path string (a/b/c)

func MockPathScopeWebsite

func MockPathScopeWebsite(id int64, path string) string

MockPathScopeWebsite creates for testing a fully qualified path for the website scope from a Scope ID and a path string (a/b/c)

func MockString

func MockString(f func(path string) string) mockOptionFunc

MockString returns a function which can be used in the NewMockReader(). Your function returns a string value from a given path.

func MockTime

func MockTime(f func(path string) time.Time) mockOptionFunc

MockTime returns a function which can be used in the NewMockReader(). Your function returns a Time value from a given path.

func ScopeGroupNames

func ScopeGroupNames() (r utils.StringSlice)

ScopeGroupNames returns a slice containing all constant names

Types

type ArgFunc

type ArgFunc func(*arg)

ArgFunc Argument function to be used as variadic argument in ScopeKey() and ScopeKeyValue()

func NoBubble

func NoBubble() ArgFunc

NoBubble disables the fallback to the default scope when a value in the current scope not exists.

func Path

func Path(paths ...string) ArgFunc

Path option function to specify the configuration path. If one argument has been provided then it must be a full valid path. If more than one argument has been provided then the arguments will be joined together. Panics if nil arguments will be provided.

func Scope

func Scope(s ScopeGroup, r ScopeIDer) ArgFunc

Scope sets the scope using the ScopeGroup and a config.ScopeIDer. A config.ScopeIDer can contain an ID from a website or a store. Make sure the correct ScopeGroup has also been set. If config.ScopeIDer is nil the scope will fallback to default scope.

func ScopeStore

func ScopeStore(r ScopeIDer) ArgFunc

ScopeStore wrapper helper function. See Scope()

func ScopeWebsite

func ScopeWebsite(r ScopeIDer) ArgFunc

ScopeWebsite wrapper helper function. See Scope()

func Value

func Value(v interface{}) ArgFunc

Value sets the value for a scope key.

func ValueReader

func ValueReader(r io.Reader) ArgFunc

ValueReader sets the value for a scope key using the io.Reader interface. If asserting to a io.Closer is successful then Close() will be called.

type DefaultMap

type DefaultMap map[string]interface{}

DefaultMap contains the default aka global configuration of a package

type Field

type Field struct {
	// ID unique ID and NOT merged with others. 3rd and final part of the path.
	ID string
	// Type is used for the front end on how to display a Field
	Type    FieldTyper `json:",omitempty"`
	Label   string     `json:",omitempty"`
	Comment string     `json:",omitempty"`
	// Scope: bit value eg: showInDefault="1" showInWebsite="1" showInStore="1"
	Scope     ScopePerm `json:",omitempty"`
	SortOrder int       `json:",omitempty"`
	// Visible used for configuration settings which are not exposed to the user.
	// In Magento2 they do not have an entry in the system.xml
	Visible Visible `json:",omitempty"`
	// SourceModel defines how to retrieve all option values
	SourceModel FieldSourceModeller `json:",omitempty"`
	// BackendModel defines how to save and load? the data
	BackendModel FieldBackendModeller `json:",omitempty"`
	// Default can contain any default config value: float64, int64, string, bool
	Default interface{} `json:",omitempty"`
}

Element contains the final path element of a configuration. @see magento2/app/code/Magento/Config/etc/system_file.xsd

type FieldBackendModeller

type FieldBackendModeller interface {
	Construct(ModelConstructor) error
	AddData(interface{})
	Save() error
}

FieldBackendModeller defines how to save and load the data @todo rethink AddData In Magento slang: beforeSave() and afterLoad(). The Construct() must be used because NOT all fields of ModelConstructor are available during init process and can of course change during the running app. Also to prevent circular dependencies.

type FieldSlice

type FieldSlice []*Field

FieldSlice contains a set of Fields

func (*FieldSlice) Append

func (fs *FieldSlice) Append(f ...*Field) *FieldSlice

Append adds *Field (variadic) to the FieldSlice

func (FieldSlice) FindByID

func (fs FieldSlice) FindByID(id string) (*Field, error)

FindByID returns a Field pointer or nil if not found

func (*FieldSlice) Len

func (fs *FieldSlice) Len() int

func (*FieldSlice) Less

func (fs *FieldSlice) Less(i, j int) bool

func (*FieldSlice) Merge

func (fs *FieldSlice) Merge(fields ...*Field) error

Merge copies the data from a Section into this slice. Appends if ID is not found in this slice otherwise overrides struct fields if not empty.

func (*FieldSlice) Sort

func (fs *FieldSlice) Sort() *FieldSlice

Sort convenience helper

func (*FieldSlice) Swap

func (fs *FieldSlice) Swap(i, j int)

type FieldSourceModeller

type FieldSourceModeller interface {
	Construct(ModelConstructor) error
	Options() ValueLabelSlice
}

FieldSourceModeller defines how to retrieve all option values. Mostly used for frontend output. The Construct() must be used because NOT all fields of ModelConstructor are available during init process and can of course change during the running app. Also to prevent circular dependencies.

type FieldType

type FieldType uint8

FieldType used in constants to define the frontend and input type

const (
	TypeButton FieldType = iota + 1 // must be + 1 because 0 is not set
	TypeCustom
	TypeLabel
	TypeHidden
	TypeImage
	TypeObscure
	TypeMultiselect
	TypeSelect
	TypeText
	TypeTextarea
	TypeTime
)

func (FieldType) MarshalJSON

func (i FieldType) MarshalJSON() ([]byte, error)

MarshalJSON implements marshaling into a human readable string. @todo UnMarshal

func (FieldType) String

func (i FieldType) String() string

func (FieldType) ToHTML

func (i FieldType) ToHTML() []byte

ToHTML noop function to satisfies the interface of Field.Type

func (FieldType) Type

func (i FieldType) Type() FieldType

Type returns the current field type and satisfies the interface of Field.Type

type FieldTyper

type FieldTyper interface {
	Type() FieldType
	ToHTML() []byte // @see \Magento\Framework\Data\Form\Element\AbstractElement
}

FieldTyper defines which front end type a configuration value is and generates the HTML for it

type Group

type Group struct {
	// ID unique ID and merged with others. 2nd part of the path.
	ID      string
	Label   string `json:",omitempty"`
	Comment string `json:",omitempty"`
	// Scope: bit value eg: showInDefault="1" showInWebsite="1" showInStore="1"
	Scope     ScopePerm `json:",omitempty"`
	SortOrder int       `json:",omitempty"`
	Fields    FieldSlice
}

Group defines the layout of a group containing multiple Fields

type GroupSlice

type GroupSlice []*Group

GroupSlice contains a set of Groups

func (*GroupSlice) Append

func (gs *GroupSlice) Append(g ...*Group) *GroupSlice

Append adds *Group (variadic) to the GroupSlice

func (GroupSlice) FindByID

func (gs GroupSlice) FindByID(id string) (*Group, error)

FindByID returns a Group pointer or nil if not found

func (*GroupSlice) Len

func (gs *GroupSlice) Len() int

func (*GroupSlice) Less

func (gs *GroupSlice) Less(i, j int) bool

func (*GroupSlice) Merge

func (gs *GroupSlice) Merge(groups ...*Group) error

Merge copies the data from a groups into this slice. Appends if ID is not found in this slice otherwise overrides struct fields if not empty.

func (*GroupSlice) Sort

func (gs *GroupSlice) Sort() *GroupSlice

Sort convenience helper

func (*GroupSlice) Swap

func (gs *GroupSlice) Swap(i, j int)

func (GroupSlice) ToJSON

func (gs GroupSlice) ToJSON() string

ToJSON transforms the whole slice into JSON

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager main configuration struct

var (

	// TableCollection handles all tables and its columns. init() in generated Go file will set the value.
	TableCollection csdb.TableStructureSlice

	// DefaultManager provides a default manager
	DefaultManager *Manager
)

func NewManager

func NewManager() *Manager

NewManager creates the main new configuration for all scopes: default, website and store

func (*Manager) AllKeys

func (m *Manager) AllKeys() []string

AllKeys return all keys regardless where they are set

func (*Manager) ApplyCoreConfigData

func (m *Manager) ApplyCoreConfigData(dbrSess dbr.SessionRunner) error

ApplyCoreConfigData reads the table core_config_data into the Manager and overrides existing values. If the column value is NULL entry will be ignored.

func (*Manager) ApplyDefaults

func (m *Manager) ApplyDefaults(ss Sectioner) *Manager

ApplyDefaults reads the map and applies the keys and values to the default configuration

func (*Manager) GetBool

func (m *Manager) GetBool(o ...ArgFunc) bool

GetBool returns bool from the manager. Example usage see GetString.

func (*Manager) GetDateTime

func (m *Manager) GetDateTime(o ...ArgFunc) time.Time

GetDateTime returns a date and time object from the manager. Example usage see GetString.

func (*Manager) GetFloat64

func (m *Manager) GetFloat64(o ...ArgFunc) float64

GetFloat64 returns a float64 from the manager. Example usage see GetString.

func (*Manager) GetInt

func (m *Manager) GetInt(o ...ArgFunc) int

GetInt returns an int from the manager. Example usage see GetString.

func (*Manager) GetString

func (m *Manager) GetString(o ...ArgFunc) string

GetString returns a string from the manager. Example usage: Default value: GetString(config.Path("general/locale/timezone")) Website value: GetString(config.Path("general/locale/timezone"), config.ScopeWebsite(w)) Store value: GetString(config.Path("general/locale/timezone"), config.ScopeStore(s))

func (*Manager) GetStringSlice

func (m *Manager) GetStringSlice(o ...ArgFunc) []string

@todo use the backend model of a config value. most/all magento string slices are comma lists.

func (*Manager) IsSet

func (m *Manager) IsSet(o ...ArgFunc) bool

IsSet checks if a key is in the config. Does not bubble.

func (*Manager) Write

func (m *Manager) Write(o ...ArgFunc) error

Write puts a value back into the manager. Example usage: Default Scope: Write(config.Path("currency", "option", "base"), config.Value("USD")) Website Scope: Write(config.Path("currency", "option", "base"), config.Value("EUR"), config.ScopeWebsite(w)) Store Scope: Write(config.Path("currency", "option", "base"), config.ValueReader(resp.Body), config.ScopeStore(s))

type MockReader

type MockReader struct {
	// contains filtered or unexported fields
}

MockReader used for testing. Contains functions which will be called in the appropriate methods of interface config.Reader.

func NewMockReader

func NewMockReader(opts ...mockOptionFunc) *MockReader

NewMockReader used for testing

func (*MockReader) GetBool

func (sr *MockReader) GetBool(opts ...ArgFunc) bool

func (*MockReader) GetDateTime

func (sr *MockReader) GetDateTime(opts ...ArgFunc) time.Time

func (*MockReader) GetFloat64

func (sr *MockReader) GetFloat64(opts ...ArgFunc) float64

func (*MockReader) GetInt

func (sr *MockReader) GetInt(opts ...ArgFunc) int

func (*MockReader) GetString

func (sr *MockReader) GetString(opts ...ArgFunc) string

type ModelConstructor

type ModelConstructor struct {
	// Scope contains a website/store ID or nil (=default scope)
	Scope ScopeIDer
	// ConfigReader returns the configuration reader and never nil
	ConfigReader Reader
}

ModelConstructor implements different fields/functions which can be differently used by the FieldSourceModeller or FieldBackendModeller types. Nearly all functions will return not nil. The Construct() function takes what it needs.

type Reader

type Reader interface {
	GetString(...ArgFunc) string
	GetBool(...ArgFunc) bool
	GetFloat64(o ...ArgFunc) float64
	GetInt(o ...ArgFunc) int
	GetDateTime(o ...ArgFunc) time.Time
}

Reader implements how to receive thread safe a configuration value from a path and or scope.

type ScopeCode

type ScopeCode string

Code is convenience helper to satisfy the interface ScopeCoder and ScopeIDer.

func (ScopeCode) ScopeCode

func (c ScopeCode) ScopeCode() string

ScopeCode is convenience helper to satisfy the interface ScopeCoder

func (ScopeCode) ScopeID

func (c ScopeCode) ScopeID() int64

ScopeID is a noop method receiver to satisfy the interface ScopeIDer

type ScopeCoder

type ScopeCoder interface {
	ScopeCode() string
}

ScopeCoder implements how to get an object by Code which can be website or store code. Groups doesn't have codes.

type ScopeGroup

type ScopeGroup uint8

ScopeGroup used in constants where default is the lowest and store the highest. Func String() attached. Part of ScopePerm.

const (
	// Scope*ID defines the overall scopes in a configuration. If a Section/Group/Field
	// can be shown in the current selected scope.
	ScopeAbsentID ScopeGroup = iota // order of the constants is used for comparison
	ScopeDefaultID
	ScopeWebsiteID
	ScopeGroupID
	ScopeStoreID
)

func GetScopeGroup

func GetScopeGroup(s string) ScopeGroup

func (ScopeGroup) String

func (i ScopeGroup) String() string

String human readable name of ScopeGroup. For Marshaling see ScopePerm

type ScopeID

type ScopeID int64

ID is convenience helper to satisfy the interface ScopeIDer.

func (ScopeID) ScopeID

func (i ScopeID) ScopeID() int64

ScopeID is convenience helper to satisfy the interface ScopeIDer

type ScopeIDer

type ScopeIDer interface {
	ScopeID() int64
}

ScopeIDer implements how to get the ID. If ScopeIDer implements ScopeCoder then ScopeCoder has precedence. ID can be any of the website, group or store IDs.

type ScopePerm

type ScopePerm uint64

ScopePerm is a bit set and used for permissions, ScopeGroup is not a part of this bit set. Type ScopeGroup is a subpart of ScopePerm

func NewScopePerm

func NewScopePerm(scopes ...ScopeGroup) ScopePerm

NewScopePerm returns a new permission container

func (*ScopePerm) All

func (bits *ScopePerm) All() ScopePerm

All applies all scopes

func (ScopePerm) Has

func (bits ScopePerm) Has(s ScopeGroup) bool

Has checks if ScopeGroup is in ScopeBits

func (ScopePerm) Human

func (bits ScopePerm) Human() utils.StringSlice

Human readable representation of the permissions

func (ScopePerm) MarshalJSON

func (bits ScopePerm) MarshalJSON() ([]byte, error)

MarshalJSON implements marshaling into an array or null if no bits are set. @todo UnMarshal

func (*ScopePerm) Set

func (bits *ScopePerm) Set(scopes ...ScopeGroup) ScopePerm

Set takes a variadic amount of ScopeGroup to set them to ScopeBits

type Section

type Section struct {
	// ID unique ID and merged with others. 1st part of the path.
	ID    string
	Label string `json:",omitempty"`
	// Scope: bit value eg: showInDefault="1" showInWebsite="1" showInStore="1"
	Scope     ScopePerm `json:",omitempty"`
	SortOrder int       `json:",omitempty"`
	// Permission some kind of ACL if someone is allowed for no,read or write access @todo
	Permission uint `json:",omitempty"`
	Groups     GroupSlice
}

Section defines the layout for the configuration section which contains groups and fields.

type SectionSlice

type SectionSlice []*Section

SectionSlice contains a set of Sections. Some nifty helper functions exists.

func NewConfiguration

func NewConfiguration(sections ...*Section) SectionSlice

NewConfiguration creates a new validated SectionSlice with a three level configuration. Panics if a path is redundant.

func NewConfigurationMerge

func NewConfigurationMerge(sections ...*Section) SectionSlice

NewConfigurationMerge creates a new validated SectionSlice with a three level configuration. Before validation, slices are all merged together. Panics if a path is redundant. Only use this function if your package configuration really has duplicated entries.

func (*SectionSlice) Append

func (ss *SectionSlice) Append(s ...*Section) *SectionSlice

Append adds 0..n *Section

func (SectionSlice) Defaults

func (ss SectionSlice) Defaults() DefaultMap

Defaults iterates over all slices, creates a path and uses the default value to return a map.

func (SectionSlice) FindByID

func (ss SectionSlice) FindByID(id string) (*Section, error)

FindByID returns a Section pointer or nil if not found. Please check for nil and do not a

func (SectionSlice) FindFieldByPath

func (ss SectionSlice) FindFieldByPath(paths ...string) (*Field, error)

FindGroupByPath searches for a field using the all three path segments. If one argument is given then considered as the full path e.g. a/b/c If three arguments are given then each argument will be treated as a path part.

func (SectionSlice) FindGroupByPath

func (ss SectionSlice) FindGroupByPath(paths ...string) (*Group, error)

FindGroupByPath searches for a group using the first two path segments. If one argument is given then considered as the full path e.g. a/b/c If two or more arguments are given then each argument will be treated as a path part.

func (*SectionSlice) Len

func (ss *SectionSlice) Len() int

func (*SectionSlice) Less

func (ss *SectionSlice) Less(i, j int) bool

func (*SectionSlice) Merge

func (ss *SectionSlice) Merge(sections ...*Section) error

Merge merges n Sections into the current slice. Behaviour for duplicates: Last item wins.

func (*SectionSlice) MergeMultiple

func (ss *SectionSlice) MergeMultiple(sSlices ...SectionSlice) error

MergeMultiple merges n SectionSlices into the current slice. Behaviour for duplicates: Last item wins.

func (*SectionSlice) Sort

func (ss *SectionSlice) Sort() *SectionSlice

Sort convenience helper

func (*SectionSlice) SortAll

func (ss *SectionSlice) SortAll() *SectionSlice

SortAll recursively sorts all slices

func (*SectionSlice) Swap

func (ss *SectionSlice) Swap(i, j int)

func (SectionSlice) ToJSON

func (ss SectionSlice) ToJSON() string

ToJSON transforms the whole slice into JSON

func (SectionSlice) TotalFields

func (ss SectionSlice) TotalFields() int

TotalFields calculates the total amount of all fields

func (SectionSlice) Validate

func (ss SectionSlice) Validate() error

Validate checks for duplicated configuration paths in all three hierarchy levels.

type Sectioner

type Sectioner interface {
	// Defaults generates the default configuration from all fields. Key is the path and value the value.
	Defaults() DefaultMap
}

Sectioner at the moment only for testing

type URLType

type URLType uint8

UrlType defines the type of the URL. Used in const declaration. @see https://github.com/magento/magento2/blob/0.74.0-beta7/lib/internal/Magento/Framework/UrlInterface.php#L13

const (
	URLTypeAbsent URLType = iota
	// UrlTypeWeb defines the ULR type to generate the main base URL.
	URLTypeWeb
	// UrlTypeStatic defines the url to the static assets like css, js or theme images
	URLTypeStatic
	// UrlTypeLink hmmm
	// UrlTypeLink
	// UrlTypeMedia defines the ULR type for generating URLs to product photos
	URLTypeMedia
)

type ValueLabel

type ValueLabel struct {
	Value, Label string
}

ValueLabel contains a stringyfied value and a label for printing in a browser / JS api.

type ValueLabelSlice

type ValueLabelSlice []ValueLabel

ValueLabelSlice type is returned by the SourceModel.Options() interface

func (ValueLabelSlice) Len

func (s ValueLabelSlice) Len() int

func (ValueLabelSlice) SortByLabel

SortByLabel sorts by label in asc or desc direction

func (ValueLabelSlice) SortByValue

SortByValue sorts by label in asc or desc direction

func (ValueLabelSlice) Swap

func (s ValueLabelSlice) Swap(i, j int)

func (ValueLabelSlice) ToJSON

func (s ValueLabelSlice) ToJSON() string

ToJSON returns a JSON string

type Visible

type Visible uint8

Visible because GoLang bool cannot be nil 8-) and also in love to https://github.com/magento/magento2/blob/0.74.0-beta9/app/code/Magento/Catalog/Model/Product/Attribute/Source/Status.php#L14 Main reason is to detect a change when merging section, group and field slices

const (
	VisibleAbsent Visible = iota // must start from 0
	VisibleYes
	VisibleNo
)

func (Visible) MarshalJSON

func (v Visible) MarshalJSON() ([]byte, error)

MarshalJSON implements marshaling into a human readable string. @todo UnMarshal

type Writer

type Writer interface {
	Write(...ArgFunc) error
}

Writer thread safe storing of configuration values under different paths and scopes.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL