commit
cbcc27f1a3
@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="Go" enabled="true" />
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/Active-GO.iml" filepath="$PROJECT_DIR$/.idea/Active-GO.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@ -0,0 +1,192 @@
|
|||||||
|
package errs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"core/errs/stack"
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// errCodePattern is the regular expression that defines a valid error code format.
|
||||||
|
// The error code can optionally have a module, which is separated by "::".
|
||||||
|
// The valid characters are alphanumeric characters and the symbols ":-_".
|
||||||
|
errCodePattern string = "^[a-zA-Z0-9._-]+(::[a-zA-Z0-9._-]+)?$"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ModuleSeparator is the separator used between the module and value parts of the error code.
|
||||||
|
ModuleSeparator string = "::"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Module configuration
|
||||||
|
const moduleName = "core.errs" + ModuleSeparator
|
||||||
|
|
||||||
|
// Error messages for internal use
|
||||||
|
const (
|
||||||
|
errNilWrapMsg string = "error trying to wrap % into a nil error"
|
||||||
|
errNilCauseMsg string = "error trying to wrap % into a nil cause"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Standard error codes for common error scenarios
|
||||||
|
const (
|
||||||
|
CodePanicError string = "panic"
|
||||||
|
CodeMultiError string = "multiple-errors"
|
||||||
|
CodeParamError string = "Param"
|
||||||
|
CodeParamNilError string = "Param-nil"
|
||||||
|
CodeParamOutOfRangeError string = "Param-out-of-range"
|
||||||
|
)
|
||||||
|
|
||||||
|
// G provides a global access point for common errors and information
|
||||||
|
// This struct combines documentation links and pre-initialized error instances
|
||||||
|
var (
|
||||||
|
G = struct {
|
||||||
|
InfoHelp,
|
||||||
|
InfoLink string
|
||||||
|
|
||||||
|
ErrParam,
|
||||||
|
ErrParamNil,
|
||||||
|
ErrParamOutOfRange,
|
||||||
|
ErrInvalidError,
|
||||||
|
ErrInvalidNilError,
|
||||||
|
ErrUnknownPanicError,
|
||||||
|
ErrInvalidErrCode ErrCode
|
||||||
|
}{
|
||||||
|
InfoLink: "https://git.activething.com/go/active",
|
||||||
|
InfoHelp: "https://doc.activething.com/go/active",
|
||||||
|
|
||||||
|
ErrParam: ErrCode(CodeParamError),
|
||||||
|
ErrParamNil: ErrCode(CodeParamNilError),
|
||||||
|
ErrParamOutOfRange: ErrCode(CodeParamOutOfRangeError),
|
||||||
|
ErrUnknownPanicError: ErrCode(moduleName + "unknown-panic-error"),
|
||||||
|
ErrInvalidNilError: ErrCode(moduleName + "invalid-nil-error"),
|
||||||
|
ErrInvalidError: ErrCode(moduleName + "invalid-error"),
|
||||||
|
ErrInvalidErrCode: ErrCode(moduleName + "invalid-err-code"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// g contains private package-level variables
|
||||||
|
g = struct {
|
||||||
|
panicErrNil *ErrPanic
|
||||||
|
|
||||||
|
codeValidator *regexp.Regexp
|
||||||
|
}{
|
||||||
|
|
||||||
|
panicErrNil: NewErrPanic(G.ErrInvalidNilError),
|
||||||
|
|
||||||
|
codeValidator: regexp.MustCompile(errCodePattern),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// ToError converts any value to an error type
|
||||||
|
// Returns nil if the input is nil
|
||||||
|
// Converts []error to ErrMulti
|
||||||
|
// Uses fmt.Errorf for other types
|
||||||
|
func ToError(err any) error {
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
switch e := err.(type) {
|
||||||
|
case error:
|
||||||
|
return e
|
||||||
|
case []error:
|
||||||
|
if len(e) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return NewErrMulti(e...)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("%v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PanicRecoveredError creates an error from a recovered panic value
|
||||||
|
// Returns nil if the recovered value is nil
|
||||||
|
func PanicRecoveredError(rec any) error {
|
||||||
|
if rec == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return *NewErrPanic(ToError(rec))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap provides standard error unwrapping functionality
|
||||||
|
// Implements the unwrap interface for error chains
|
||||||
|
func Unwrap(err error) error {
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if cs, is := err.(Unwrapper); is {
|
||||||
|
return cs.Unwrap()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnwrapCause retrieves the root cause of an error chain
|
||||||
|
// Traverses the error chain looking for Causer implementation
|
||||||
|
func UnwrapCause(err error) error {
|
||||||
|
e := err
|
||||||
|
for e != nil {
|
||||||
|
cs, is := e.(Causer)
|
||||||
|
if is {
|
||||||
|
return cs.Cause()
|
||||||
|
}
|
||||||
|
e = Unwrap(e)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnwrapCauses retrieves all causes in an error chain
|
||||||
|
// Returns a slice of errors representing the cause chain
|
||||||
|
func UnwrapCauses(err error) []error {
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if al, is := err.(Causers); is {
|
||||||
|
return al.Causes()
|
||||||
|
}
|
||||||
|
var l ErrorList
|
||||||
|
e := err
|
||||||
|
for e != nil {
|
||||||
|
l = append(l, e)
|
||||||
|
e = Unwrap(e)
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnwrapList retrieves all errors in an error chain as an ErrorList
|
||||||
|
// Handles both UnwrapperList implementations and standard error chains
|
||||||
|
func UnwrapList(err error) ErrorList {
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if al, is := err.(UnwrapperList); is {
|
||||||
|
return al.Unwrap()
|
||||||
|
}
|
||||||
|
var l ErrorList
|
||||||
|
e := err
|
||||||
|
for e != nil {
|
||||||
|
l = append(l, e)
|
||||||
|
e = Unwrap(e)
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnwrapTrace retrieves the stack trace from an error
|
||||||
|
func UnwrapTrace(err error) stack.Stack {
|
||||||
|
return stack.UnwrapStack(err, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WrapError combines two errors into a single error, establishing a cause relationship.
|
||||||
|
// If either error is nil, the non-nil error is returned.
|
||||||
|
// Otherwise, a new error is returned that has the first error as the cause.
|
||||||
|
func WrapError(err, cause error) error {
|
||||||
|
if err == nil {
|
||||||
|
return cause
|
||||||
|
}
|
||||||
|
if cause == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return *NewErrWithCause(err, cause)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateCode check if un err code is valid
|
||||||
|
func ValidateCode(code string) bool {
|
||||||
|
return g.codeValidator.MatchString(code)
|
||||||
|
}
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package errs
|
||||||
|
|
||||||
|
// Causer is an interface for types that can provide an underlying cause of an error.
|
||||||
|
// It is commonly used in error wrapping and error chain scenarios to access the
|
||||||
|
// root cause of an error condition.
|
||||||
|
type (
|
||||||
|
// Causer defines the interface for error types that can reveal their underlying cause.
|
||||||
|
// This interface is useful for implementing error wrapping patterns and
|
||||||
|
// for building error chains that preserve cause information.
|
||||||
|
Causer interface {
|
||||||
|
// Cause returns the underlying error that caused this error, if any.
|
||||||
|
// If there is no underlying error, it may return nil.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - error: The underlying error that caused this error, or nil if none exists
|
||||||
|
Cause() error
|
||||||
|
}
|
||||||
|
|
||||||
|
// CauseFnc is a function type that implements the Causer interface.
|
||||||
|
// It allows for dynamic generation of error causes and can be used
|
||||||
|
// to create error causes lazily or based on runtime conditions.
|
||||||
|
//
|
||||||
|
// The function is called when ErrWithCause() is invoked on the CauseFnc.
|
||||||
|
CauseFnc func() error
|
||||||
|
)
|
||||||
|
|
||||||
|
// Cause implements the Causer interface for CauseFnc.
|
||||||
|
// It executes the function and returns its error result.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - error: The result of executing the CauseFnc
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// cause := CauseFnc(func() error {
|
||||||
|
// return errors.New("root cause")
|
||||||
|
// })
|
||||||
|
// err := cause.ErrWithCause() // returns "root cause" error
|
||||||
|
func (f CauseFnc) Cause() error {
|
||||||
|
return f()
|
||||||
|
}
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package errs
|
||||||
|
|
||||||
|
type (
|
||||||
|
// Causers is an interface for types that can provide multiple underlying causes
|
||||||
|
// of an error. This is useful in scenarios where an error condition might have
|
||||||
|
// resulted from multiple underlying issues or failures.
|
||||||
|
//
|
||||||
|
// This interface is particularly useful for:
|
||||||
|
// - Aggregated error reporting
|
||||||
|
// - Parallel operation failures
|
||||||
|
// - Multiple validation errors
|
||||||
|
// - Complex error scenarios with multiple root causes
|
||||||
|
Causers interface {
|
||||||
|
// Causes returns a slice of errors that contributed to this error condition.
|
||||||
|
// The order of errors in the slice may be significant depending on the
|
||||||
|
// implementation.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - []error: A slice of underlying errors that caused this error condition.
|
||||||
|
// May return an empty slice if there are no causes.
|
||||||
|
Causes() []error
|
||||||
|
}
|
||||||
|
|
||||||
|
// CausesFnc is a function type that implements the Causers interface.
|
||||||
|
// It allows for dynamic generation of multiple error causes and can be used
|
||||||
|
// to create error causes lazily or based on runtime conditions.
|
||||||
|
//
|
||||||
|
// Common use cases include:
|
||||||
|
// - Lazy evaluation of error causes
|
||||||
|
// - Dynamic error aggregation
|
||||||
|
// - Conditional error collection
|
||||||
|
CausesFnc func() []error
|
||||||
|
)
|
||||||
|
|
||||||
|
// Causes implements the Causers interface for CausesFnc.
|
||||||
|
// It executes the function and returns its slice of errors.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - []error: The slice of errors returned by executing the CausesFnc
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// causes := CausesFnc(func() []error {
|
||||||
|
// return []error{
|
||||||
|
// errors.New("first cause"),
|
||||||
|
// errors.New("second cause"),
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// errs := causes.Causes() // returns slice with both errors
|
||||||
|
func (f CausesFnc) Causes() []error {
|
||||||
|
return f()
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package errs
|
||||||
|
|
||||||
|
type Coder interface {
|
||||||
|
Code() string
|
||||||
|
}
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
package errs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ErrCode is a custom error type that represents an error code.
|
||||||
|
// It may include a module and a value, separated by "::".
|
||||||
|
type ErrCode string
|
||||||
|
|
||||||
|
// MakeErrCode creates a new ErrCode from the given string.
|
||||||
|
// It validates that the string is non-empty and matches the predefined error code pattern.
|
||||||
|
// If the string is invalid, it panics.
|
||||||
|
func MakeErrCode(err string) ErrCode {
|
||||||
|
|
||||||
|
if len(err) == 0 || !g.codeValidator.MatchString(err) {
|
||||||
|
// If the error code is invalid, panic with a predefined error Msg.
|
||||||
|
fmt.Println(err)
|
||||||
|
panic(G.ErrInvalidErrCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the created ErrCode.
|
||||||
|
return ErrCode(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error implements the error interface for ErrCode.
|
||||||
|
// It returns the error code as a string.
|
||||||
|
func (e ErrCode) Error() string {
|
||||||
|
return string(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the error code as a string representation.
|
||||||
|
func (e ErrCode) String() string {
|
||||||
|
return string(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Module extracts and returns the module part of the error code.
|
||||||
|
// If there is no module, it returns an empty string.
|
||||||
|
func (e ErrCode) Module() string {
|
||||||
|
// Check if the error code has a module, using the module separator "::".
|
||||||
|
if b, has := strings.CutSuffix(string(e), ModuleSeparator); has {
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
// If no module is found, return an empty string.
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value extracts and returns the value part of the error code.
|
||||||
|
// If there is no value, it returns the entire error code.
|
||||||
|
func (e ErrCode) Value() string {
|
||||||
|
// Check if the error code has a value, using the module separator "::".
|
||||||
|
if b, has := strings.CutPrefix(string(e), ModuleSeparator); has {
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
// If no module part is found, return the entire error code (it is considered as the value).
|
||||||
|
return string(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsValid checks whether the error code is valid according to the defined pattern.
|
||||||
|
// It returns true if the error code matches the regular expression, otherwise false.
|
||||||
|
func (e ErrCode) IsValid() bool {
|
||||||
|
// Use the code validator to check if the error code matches the pattern.
|
||||||
|
return g.codeValidator.MatchString(string(e))
|
||||||
|
}
|
||||||
|
|
||||||
|
// With returns a WrapErrWith instance containing this ErrCode
|
||||||
|
// Enables using the wrapper's additional error handling functionality
|
||||||
|
func (e ErrCode) With() ErrWith {
|
||||||
|
return MakeErrWith(e)
|
||||||
|
}
|
||||||
@ -0,0 +1,82 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package errs
|
||||||
|
|
||||||
|
// ErrMulti is a struct that represents multiple errors as a single error
|
||||||
|
// It embeds ErrorList to provide all error list functionality
|
||||||
|
type (
|
||||||
|
ErrMulti struct {
|
||||||
|
ErrorList
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewErrMulti creates a new ErrMulti instance from variable number of errors
|
||||||
|
// It cleans the error list by removing nil errors before creating the instance
|
||||||
|
// Returns a pointer to the new ErrMulti
|
||||||
|
func NewErrMulti(err ...error) *ErrMulti {
|
||||||
|
return &ErrMulti{ErrorList: ErrorList(err).Clean()}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewErrMultiIf creates a new error from a slice of errors
|
||||||
|
// Returns nil if the input slice is empty
|
||||||
|
// Returns an ErrMulti pointer containing the errors otherwise
|
||||||
|
func NewErrMultiIf(errors []error) error {
|
||||||
|
if len(errors) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &ErrMulti{errors}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code returns the error code for multi-error situations
|
||||||
|
// Returns the constant CodeMultiError
|
||||||
|
func (e ErrMulti) Code() string {
|
||||||
|
return CodeMultiError
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error implements the error interface
|
||||||
|
// Returns the CodeMultiError as the error Msg
|
||||||
|
func (e ErrMulti) Error() string {
|
||||||
|
return CodeMultiError
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap implements the unwrap interface for multiple errors
|
||||||
|
// Returns the underlying slice of errors
|
||||||
|
func (e ErrMulti) Unwrap() []error {
|
||||||
|
return e.ErrorList
|
||||||
|
}
|
||||||
|
|
||||||
|
// Causes returns all underlying errors
|
||||||
|
// This is an alias for Unwrap() providing a more semantic name
|
||||||
|
func (e ErrMulti) Causes() []error {
|
||||||
|
return e.ErrorList
|
||||||
|
}
|
||||||
|
|
||||||
|
// With returns a WrapErrWith instance containing this ErrMulti
|
||||||
|
// Enables using the wrapper's additional error handling functionality
|
||||||
|
func (e ErrMulti) With() ErrWith {
|
||||||
|
return MakeErrWith(e)
|
||||||
|
}
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package errs
|
||||||
|
|
||||||
|
// ErrPanic is a custom error type that represents a specific error case involving a panic.
|
||||||
|
//
|
||||||
|
// Fields:
|
||||||
|
// - cause: The underlying error that triggered the panic, if any.
|
||||||
|
type ErrPanic struct {
|
||||||
|
cause error
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewErrPanic creates a new instance of ErrPanic.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - cause: The underlying error that caused the panic.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - A pointer to the newly created ErrPanic instance.
|
||||||
|
func NewErrPanic(cause error) *ErrPanic {
|
||||||
|
return &ErrPanic{cause: cause}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error returns a string representation of the ErrPanic error.
|
||||||
|
// This is the implementation of the error interface.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - A constant string (CodePanicError) representing the error message.
|
||||||
|
func (e ErrPanic) Error() string {
|
||||||
|
return CodePanicError // Note: Ensure CodePanicError is defined elsewhere.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap provides access to the underlying error (if any) in the ErrPanic instance.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - The underlying error that caused the panic, or nil if there is no cause.
|
||||||
|
// Note: Currently, this implementation always returns nil.
|
||||||
|
func (e ErrPanic) Unwrap() error {
|
||||||
|
return nil // Consider returning e.cause for compatibility with errors.Unwrap.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cause retrieves the underlying cause of the ErrPanic error.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - The underlying error that caused the panic.
|
||||||
|
func (e ErrPanic) Cause() error {
|
||||||
|
return e.cause
|
||||||
|
}
|
||||||
|
|
||||||
|
// With wraps the ErrPanic instance into an ErrWith structure for additional context.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - An ErrWith instance containing the ErrPanic error.
|
||||||
|
func (e ErrPanic) With() ErrWith {
|
||||||
|
return MakeErrWith(e)
|
||||||
|
}
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package errs
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type (
|
||||||
|
ErrParam struct {
|
||||||
|
code string
|
||||||
|
Param string
|
||||||
|
Msg string
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewErrParam(param string, msgf string, params ...any) *ErrParam {
|
||||||
|
return &ErrParam{
|
||||||
|
code: CodeParamError,
|
||||||
|
Param: param,
|
||||||
|
Msg: fmt.Sprintf(msgf, params...)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewErrNilParam(param string, msgf string, params ...any) *ErrParam {
|
||||||
|
return &ErrParam{
|
||||||
|
code: CodeParamNilError,
|
||||||
|
Param: param,
|
||||||
|
Msg: fmt.Sprintf(msgf, params...)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrParam) Code() string {
|
||||||
|
return e.code
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrParam) Error() string {
|
||||||
|
return e.code
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrParam) Message() string {
|
||||||
|
return e.Msg
|
||||||
|
}
|
||||||
|
|
||||||
|
// With returns a WrapErrWith instance containing this ErrParam
|
||||||
|
// Enables using the wrapper's additional error handling functionality
|
||||||
|
func (e ErrParam) With() ErrWith {
|
||||||
|
return MakeErrWith(e)
|
||||||
|
}
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package errs
|
||||||
|
|
||||||
|
// ErrWith is a struct that wraps an error and provides additional error handling functionality
|
||||||
|
// It embeds the error interface to maintain error compatibility
|
||||||
|
type ErrWith struct {
|
||||||
|
error
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewErrWith(err error) *ErrWith {
|
||||||
|
if err == nil {
|
||||||
|
panic(g.panicErrNil)
|
||||||
|
}
|
||||||
|
return &ErrWith{err}
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeErrWith(err error) ErrWith {
|
||||||
|
return *NewErrWith(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap returns the wrapped error
|
||||||
|
// This method complies with Go's error unwrapping convention
|
||||||
|
func (w ErrWith) Unwrap() error {
|
||||||
|
return w.error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cause creates a new error with cause by wrapping the current error
|
||||||
|
// and associating it with a cause error
|
||||||
|
// Returns a pointer to ErrWithCause containing both errors
|
||||||
|
func (w ErrWith) Cause(cause error) *ErrWithCause {
|
||||||
|
return NewErrWithCause(w.error, cause)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message creates a new error with an additional Msg
|
||||||
|
// Returns a pointer to ErrWithMessage containing the original error and new Msg
|
||||||
|
func (w ErrWith) Message(msg string) *ErrWithMessage {
|
||||||
|
return NewErrWithMessage(w.error, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessageF creates a new error with a formatted Msg using printf-style formatting
|
||||||
|
// params are used to format the Msg string
|
||||||
|
// Returns a pointer to ErrWithMessage containing the original error and formatted Msg
|
||||||
|
func (w ErrWith) MessageF(format string, params ...any) *ErrWithMessage {
|
||||||
|
return NewErrWithMessageF(w.error, format, params...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stack creates a new error with stack trace information
|
||||||
|
// offset parameter determines how many stack frames to skip
|
||||||
|
// Returns a pointer to ErrWithStack containing the original error and stack trace
|
||||||
|
func (w ErrWith) Stack(offset int) *ErrWithStack {
|
||||||
|
return NewErrWithStack(w.error, offset)
|
||||||
|
}
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package errs
|
||||||
|
|
||||||
|
type (
|
||||||
|
ErrWithCause struct {
|
||||||
|
error
|
||||||
|
cause error
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewErrWithCause(err error, cause error) *ErrWithCause {
|
||||||
|
if err == nil {
|
||||||
|
panic(G.ErrInvalidNilError.With().MessageF(errNilWrapMsg, "ErrWithCause"))
|
||||||
|
}
|
||||||
|
if cause == nil {
|
||||||
|
panic(G.ErrInvalidNilError.With().MessageF(errNilCauseMsg, "ErrWithCause"))
|
||||||
|
}
|
||||||
|
return &ErrWithCause{
|
||||||
|
error: err,
|
||||||
|
cause: cause,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrWithCause) Unwrap() error {
|
||||||
|
return e.error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrWithCause) Cause() error {
|
||||||
|
return e.cause
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrWithCause) With() ErrWith {
|
||||||
|
return MakeErrWith(e)
|
||||||
|
}
|
||||||
@ -0,0 +1,82 @@
|
|||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Project active2
|
||||||
|
// Active Thing (activething.com) git.activething.com/go
|
||||||
|
//
|
||||||
|
// File name errMeta.go
|
||||||
|
// Created by DEV
|
||||||
|
// Modified 24/03/2024
|
||||||
|
//
|
||||||
|
// Copyright 2024 activething.com
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
package errs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ErrWithInfo is an error type that enriches errors with additional context and metadata
|
||||||
|
// It wraps an existing error and adds fields for documentation, timing, and descriptions
|
||||||
|
type (
|
||||||
|
ErrWithInfo struct {
|
||||||
|
error // Embedded error interface
|
||||||
|
Msg string // Custom error Msg
|
||||||
|
Info string // Additional information about the error
|
||||||
|
Desc string // Detailed description of the error
|
||||||
|
Help string // Help text for resolving the error
|
||||||
|
Link string // URL to documentation or additional resources
|
||||||
|
Date time.Time // Timestamp when the error was created
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrWithInfoFnc is a function type used for the functional options pattern
|
||||||
|
// It allows flexible configuration of ErrWithInfo instances
|
||||||
|
ErrWithInfoFnc func(*ErrWithInfo)
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewErrWithInfo creates a new ErrWithInfo instance with the given error and options
|
||||||
|
// Panics if the input error is nil
|
||||||
|
// The options parameter allows customizing the error information using functional options
|
||||||
|
func NewErrWithInfo(err error, options ...ErrWithInfoFnc) *ErrWithInfo {
|
||||||
|
if err == nil {
|
||||||
|
panic(G.ErrInvalidNilError.With().MessageF(errNilWrapMsg, "ErrWithInfo"))
|
||||||
|
}
|
||||||
|
ei := &ErrWithInfo{
|
||||||
|
error: err,
|
||||||
|
Link: G.InfoLink,
|
||||||
|
Date: time.Now(),
|
||||||
|
}
|
||||||
|
for _, o := range options {
|
||||||
|
o(ei)
|
||||||
|
}
|
||||||
|
return ei
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message returns the custom Msg associated with the error
|
||||||
|
// Implements the Message() string interface
|
||||||
|
func (e ErrWithInfo) Message() string {
|
||||||
|
return e.Msg
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap returns the underlying error
|
||||||
|
// Implements the Unwrapper interface
|
||||||
|
func (e ErrWithInfo) Unwrap() error {
|
||||||
|
return e.error
|
||||||
|
}
|
||||||
|
|
||||||
|
// With returns a WrapErrWith instance containing this error
|
||||||
|
// Enables using the wrapper's additional error handling functionality
|
||||||
|
func (e ErrWithInfo) With() ErrWith {
|
||||||
|
return MakeErrWith(e)
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package errs
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type (
|
||||||
|
ErrWithMessage struct {
|
||||||
|
error
|
||||||
|
message string
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewErrWithMessage(err error, msg string) *ErrWithMessage {
|
||||||
|
if err == nil {
|
||||||
|
panic(G.ErrInvalidNilError.With().MessageF(errNilWrapMsg, "ErrWithMessage"))
|
||||||
|
}
|
||||||
|
return &ErrWithMessage{
|
||||||
|
error: err,
|
||||||
|
message: msg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewErrWithMessageF(err error, msgf string, params ...any) *ErrWithMessage {
|
||||||
|
return NewErrWithMessage(err, fmt.Sprintf(msgf, params...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrWithMessage) Message() string {
|
||||||
|
return e.message
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrWithMessage) Unwrap() error {
|
||||||
|
return e.error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrWithMessage) With() ErrWith {
|
||||||
|
return MakeErrWith(e)
|
||||||
|
}
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package errs
|
||||||
|
|
||||||
|
import "core/errs/stack"
|
||||||
|
|
||||||
|
// ErrWithStack represents an error that includes a stack trace.
|
||||||
|
// It combines an error with a stack trace, enabling stack trace preservation during error propagation.
|
||||||
|
type ErrWithStack struct {
|
||||||
|
error // Embedding the base error
|
||||||
|
Stack stack.Stack // The stack trace associated with the error
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewErrWithStack creates a new ErrWithStack instance, which includes both an error and a stack trace.
|
||||||
|
// If the provided error is nil, it will panic with an appropriate error message.
|
||||||
|
// It checks if the error implements the stack.Stacker interface to determine if it already has a stack trace.
|
||||||
|
// If the error does not have a stack trace, it creates a new one using the provided offset.
|
||||||
|
func NewErrWithStack(err error, offset int) *ErrWithStack {
|
||||||
|
if err == nil {
|
||||||
|
panic(G.ErrInvalidNilError.With().MessageF(errNilWrapMsg, "ErrWithStack")) // Panic if the error is nil
|
||||||
|
}
|
||||||
|
var st stack.Stack
|
||||||
|
// Check if the error already implements the stack.Stacker interface
|
||||||
|
tc, is := err.(stack.Stacker)
|
||||||
|
if !is {
|
||||||
|
// If the error does not implement stack.Stacker, create a new stack trace using the offset
|
||||||
|
st = stack.MakeStack(offset)
|
||||||
|
} else {
|
||||||
|
// If the error has a stack trace, use it
|
||||||
|
st = tc.Stack()
|
||||||
|
}
|
||||||
|
// Return a new ErrWithStack containing both the error and the stack trace
|
||||||
|
return &ErrWithStack{
|
||||||
|
error: err, // Set the embedded error
|
||||||
|
Stack: st, // Set the stack trace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap returns the underlying error that is wrapped by ErrWithStack.
|
||||||
|
// This allows the error to be unwrapped using Go's error handling mechanisms (e.g., errors.Is or errors.As).
|
||||||
|
func (e ErrWithStack) Unwrap() error {
|
||||||
|
return e.error // Return the embedded error
|
||||||
|
}
|
||||||
|
|
||||||
|
// With provides an ErrWith instance to allow further extension of the error.
|
||||||
|
// This method enables the chaining of additional information or metadata on top of the error.
|
||||||
|
func (e ErrWithStack) With() ErrWith {
|
||||||
|
return MakeErrWith(e) // Create and return an ErrWith instance
|
||||||
|
}
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package errs
|
||||||
|
|
||||||
|
// ErrorHandler defines an interface for objects that can handle errors
|
||||||
|
// This interface is used to abstract error handling logic
|
||||||
|
type (
|
||||||
|
ErrorHandler interface {
|
||||||
|
// HandleError processes an error according to the implementation's strategy
|
||||||
|
HandleError(err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleErrorFnc is a function type that implements ErrorHandler interface
|
||||||
|
// It allows regular functions to be used as error handlers through type conversion
|
||||||
|
HandleErrorFnc func(err error)
|
||||||
|
)
|
||||||
|
|
||||||
|
// HandleError implements the ErrorHandler interface for HandleErrorFnc
|
||||||
|
// This allows using the function directly as an ErrorHandler
|
||||||
|
func (f HandleErrorFnc) HandleError(err error) {
|
||||||
|
f(err)
|
||||||
|
}
|
||||||
@ -0,0 +1,122 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package errs
|
||||||
|
|
||||||
|
// ErrorList represents a slice of errors that provides convenient methods for error handling
|
||||||
|
type ErrorList []error
|
||||||
|
|
||||||
|
// Any returns true if the list contains at least one non-nil error
|
||||||
|
func (l ErrorList) Any() bool {
|
||||||
|
for _, e := range l {
|
||||||
|
if e != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Len returns the total length of the error list, including nil errors
|
||||||
|
func (l ErrorList) Len() int {
|
||||||
|
return len(l)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count returns the number of non-nil errors in the list
|
||||||
|
func (l ErrorList) Count() int {
|
||||||
|
c := 0
|
||||||
|
for _, e := range l {
|
||||||
|
if e != nil {
|
||||||
|
c++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// First returns the first non-nil error in the list
|
||||||
|
// If no non-nil error exists, returns nil
|
||||||
|
func (l ErrorList) First() error {
|
||||||
|
for _, e := range l {
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last returns the last non-nil error in the list
|
||||||
|
// If no non-nil error exists, returns nil
|
||||||
|
func (l ErrorList) Last() error {
|
||||||
|
for i := len(l) - 1; i >= 0; i-- {
|
||||||
|
if l[i] != nil {
|
||||||
|
return l[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append adds an error to the end of the list, regardless of whether it's nil
|
||||||
|
// Returns the modified error list
|
||||||
|
func (l ErrorList) Append(err error) ErrorList {
|
||||||
|
return append(l, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendNotNil adds an error to the list only if it's not nil
|
||||||
|
// Returns the modified error list or the original list if the error was nil
|
||||||
|
func (l ErrorList) AppendNotNil(err error) ErrorList {
|
||||||
|
if err != nil {
|
||||||
|
return append(l, err)
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset removes all errors from the list by resetting its length to zero
|
||||||
|
// Returns the emptied error list
|
||||||
|
func (l ErrorList) Reset() ErrorList {
|
||||||
|
return l[:0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean removes any nil errors from the list
|
||||||
|
// Returns a new error list containing only non-nil errors
|
||||||
|
func (l ErrorList) Clean() ErrorList {
|
||||||
|
return l.filter(func(e error) bool {
|
||||||
|
return e != nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// filter creates a new error list containing only errors that satisfy the filter function
|
||||||
|
// Returns nil if no errors match the filter criteria
|
||||||
|
func (l ErrorList) filter(filter func(error) bool) ErrorList {
|
||||||
|
rs := make([]error, 0, len(l))
|
||||||
|
for _, e := range l {
|
||||||
|
if filter(e) {
|
||||||
|
rs = append(rs, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(rs) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return rs
|
||||||
|
}
|
||||||
@ -0,0 +1,155 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package stack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Frame represents a single stack frame in a program's execution stack.
|
||||||
|
// It contains detailed information about the source code location,
|
||||||
|
// function, and package where the frame was created.
|
||||||
|
type Frame struct {
|
||||||
|
// LineNumber is the line number in the source file where this frame was created
|
||||||
|
LineNumber int
|
||||||
|
|
||||||
|
// File is the full path to the source file containing this frame
|
||||||
|
File string
|
||||||
|
|
||||||
|
// FuncName is the name of the function where this frame was created,
|
||||||
|
// with any receiver types removed
|
||||||
|
FuncName string
|
||||||
|
|
||||||
|
// Package is the full package path where this frame was created
|
||||||
|
Package string
|
||||||
|
|
||||||
|
// Counter is the program counter address for this frame
|
||||||
|
Counter uintptr
|
||||||
|
|
||||||
|
// files is an internal cache of file contents
|
||||||
|
files map[string][]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFrame creates a new Frame instance from a program counter address.
|
||||||
|
// It extracts the source code location, function name, and package information
|
||||||
|
// from the runtime stack.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - counter: Program counter address to create the frame from
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - *Frame: A new Frame instance, or nil if counter is 0
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// pc := runtime.Caller(0)
|
||||||
|
// frame := NewFrame(pc)
|
||||||
|
func NewFrame(counter uintptr) *Frame {
|
||||||
|
if counter == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
sf := &Frame{
|
||||||
|
Counter: counter,
|
||||||
|
}
|
||||||
|
fn := runtime.FuncForPC(counter)
|
||||||
|
sf.Package, sf.FuncName = packageAndName(fn)
|
||||||
|
sf.File, sf.LineNumber = fn.FileLine(counter - 1)
|
||||||
|
return sf
|
||||||
|
}
|
||||||
|
|
||||||
|
// SourceLine retrieves the actual source code line for this stack frame.
|
||||||
|
// It reads the source file and returns the line of code that created this frame.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - string: The source code line, or "unknown" if the line cannot be found
|
||||||
|
// - error: Any error encountered while reading the source file
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// frame := NewFrame(runtime.Caller(0))
|
||||||
|
// line, err := frame.SourceLine()
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
// fmt.Println("Source line:", line)
|
||||||
|
func (f Frame) SourceLine() (string, error) {
|
||||||
|
if f.LineNumber <= 0 {
|
||||||
|
return stackUnknownInfo, nil
|
||||||
|
}
|
||||||
|
file, err := os.Open(f.File)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
currentLine := 1
|
||||||
|
for scanner.Scan() {
|
||||||
|
if currentLine == f.LineNumber {
|
||||||
|
return string(bytes.Trim(scanner.Bytes(), " \t")), nil
|
||||||
|
}
|
||||||
|
currentLine++
|
||||||
|
}
|
||||||
|
_ = file.Close()
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return stackUnknownInfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// packageAndName splits a fully qualified function name into its package and function parts.
|
||||||
|
// It handles nested packages and removes any receiver type information from the function name.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - fn: Runtime function information
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - string: Package path
|
||||||
|
// - string: Function name with receiver types removed
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// fn := runtime.FuncForPC(pc)
|
||||||
|
// pkg, name := packageAndName(fn)
|
||||||
|
// // For "github.com/user/pkg.(*Type).Method"
|
||||||
|
// // pkg = "github.com/user/pkg"
|
||||||
|
// // name = "Type.Method"
|
||||||
|
func packageAndName(fn *runtime.Func) (string, string) {
|
||||||
|
nm := fn.Name()
|
||||||
|
pg := ""
|
||||||
|
if ls := strings.LastIndex(nm, "/"); ls >= 0 {
|
||||||
|
pg = nm[:ls] + "/"
|
||||||
|
nm = nm[ls+1:]
|
||||||
|
}
|
||||||
|
if pd := strings.Index(nm, "."); pd >= 0 {
|
||||||
|
pg += nm[:pd]
|
||||||
|
nm = nm[pd+1:]
|
||||||
|
}
|
||||||
|
return pg, strings.Replace(nm, "·", ".", -1)
|
||||||
|
}
|
||||||
@ -0,0 +1,162 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package stack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constantes utilizadas para la configuración y manejo de stack traces
|
||||||
|
const (
|
||||||
|
// stackSkipFrames define cuántos frames iniciales se omiten al capturar el stack
|
||||||
|
// Se omiten 2 frames para excluir las llamadas internas del sistema
|
||||||
|
stackSkipFrames = 2
|
||||||
|
|
||||||
|
// stackMaxFrames define el número máximo de frames que se capturarán
|
||||||
|
// Limita la profundidad del stack trace a 32 frames
|
||||||
|
stackMaxFrames = 32
|
||||||
|
|
||||||
|
// stackUnknownInfo es el valor por defecto cuando no se puede obtener
|
||||||
|
// información sobre un frame del stack
|
||||||
|
stackUnknownInfo = "???"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Stack represents a slice of program counters (uintptr) that point to function call locations
|
||||||
|
type Stack []uintptr
|
||||||
|
|
||||||
|
// MakeStack creates a new Stack with program counters from the current goroutine's stack trace
|
||||||
|
// Parameters:
|
||||||
|
// - offset: Number of stack frames to skip from the call point. If negative, it's set to 0
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - Stack: A slice containing program counter values for each stack frame
|
||||||
|
//
|
||||||
|
// The function captures up to stackMaxFrames frames, starting from offset+stackSkipFrames
|
||||||
|
func MakeStack(offset int) Stack {
|
||||||
|
// Create a slice to store program counters with maximum capacity
|
||||||
|
ls := make([]uintptr, stackMaxFrames)
|
||||||
|
|
||||||
|
// Ensure offset is not negative
|
||||||
|
if offset < 0 {
|
||||||
|
offset = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Capture the stack trace using runtime.Callers
|
||||||
|
// cn will contain the actual number of frames captured
|
||||||
|
cn := runtime.Callers(offset+stackSkipFrames, ls)
|
||||||
|
|
||||||
|
// Return only the slice containing valid program counters
|
||||||
|
return ls[:cn]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Frames converts the Stack's program counters into Frame objects
|
||||||
|
// that contain detailed information about each stack frame
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - []Frame: Slice of Frame objects containing function call information
|
||||||
|
func (s Stack) Frames() []Frame {
|
||||||
|
// Create a slice to store Frame objects
|
||||||
|
f := make([]Frame, len(s))
|
||||||
|
|
||||||
|
// Convert each program counter to a Frame object
|
||||||
|
for i, p := range s {
|
||||||
|
f[i] = *NewFrame(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnwrapStack extrae el Stack de un error, navegando por la cadena de errores
|
||||||
|
// si es necesario. Puede buscar también en las causas del error si se especifica.
|
||||||
|
//
|
||||||
|
// Parámetros:
|
||||||
|
// - err: El error del cual extraer el stack trace
|
||||||
|
// - cause: Si es true, también busca en las causas del error
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - Stack: El stack trace encontrado o nil si no se encuentra ninguno
|
||||||
|
func UnwrapStack(err error, cause bool) Stack {
|
||||||
|
// Si el error es nil, retorna nil
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Primero busca en la cadena principal de errores
|
||||||
|
e := err
|
||||||
|
for e != nil {
|
||||||
|
// Intenta convertir el error a Stacker
|
||||||
|
if st, is := e.(Stacker); is {
|
||||||
|
return st.Stack()
|
||||||
|
}
|
||||||
|
e = errors.Unwrap(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si cause es true, busca en las causas del error
|
||||||
|
if cause {
|
||||||
|
e = err
|
||||||
|
for e != nil {
|
||||||
|
// Busca en errores que implementan Cause() error
|
||||||
|
if cs, is := e.(interface{ Cause() error }); is {
|
||||||
|
UnwrapStack(cs.Cause(), cause)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Busca en errores que implementan Causes() []error
|
||||||
|
if cs, is := e.(interface{ Causes() []error }); is {
|
||||||
|
if tc := unwrapStackMulti(cs.Causes()); tc != nil {
|
||||||
|
return tc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Busca en errores que implementan Unwrap() []error
|
||||||
|
if cs, is := e.(interface{ Unwrap() []error }); is {
|
||||||
|
if tc := unwrapStackMulti(cs.Unwrap()); tc != nil {
|
||||||
|
return tc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
e = errors.Unwrap(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// unwrapStackMulti busca un Stack en un slice de errores
|
||||||
|
//
|
||||||
|
// Parámetros:
|
||||||
|
// - ers: Slice de errores a examinar
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - Stack: El primer stack trace encontrado o nil si no se encuentra ninguno
|
||||||
|
func unwrapStackMulti(ers []error) Stack {
|
||||||
|
for _, e := range ers {
|
||||||
|
if tc := UnwrapStack(e, true); tc != nil {
|
||||||
|
return tc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package stack
|
||||||
|
|
||||||
|
// Stacker defines an interface for types that can provide their stack trace
|
||||||
|
// Types implementing this interface must be able to return their current call stack
|
||||||
|
type Stacker interface {
|
||||||
|
// Stack returns the current stack trace
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - Stack: A slice of program counters representing the call stack
|
||||||
|
//
|
||||||
|
// This method should capture and return the relevant stack frames
|
||||||
|
// at the point of invocation
|
||||||
|
Stack() Stack
|
||||||
|
}
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package errs
|
||||||
|
|
||||||
|
// TryCatch struct defines the structure for handling Try-Catch-Finally operations.
|
||||||
|
// - Try: A function that will be executed in the "try" block.
|
||||||
|
// - Catch: A function that will be executed if a panic occurs in the "try" block (catching the panic).
|
||||||
|
// - Finally: A function that will be executed at the end of the execution, regardless of success or failure (finally block).
|
||||||
|
type TryCatch struct {
|
||||||
|
Try func(params ...any) // Function to execute in the "try" block
|
||||||
|
Catch func(err error) // Function to handle errors if a panic occurs (catch block)
|
||||||
|
Finally func(params ...any) // Function to execute in the "finally" block (always runs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do executes the Try, Catch, and Finally blocks based on the provided parameters.
|
||||||
|
// It will:
|
||||||
|
// 1. Execute the Try block.
|
||||||
|
// 2. Catch any panics that occur during the Try block execution and pass them to the Catch block.
|
||||||
|
// 3. Always execute the Finally block at the end, whether an error occurred or not.
|
||||||
|
func (c TryCatch) Do(params ...any) {
|
||||||
|
// If a Finally block is provided, defer its execution to ensure it runs last.
|
||||||
|
if c.Finally != nil {
|
||||||
|
defer c.Finally(params...)
|
||||||
|
}
|
||||||
|
|
||||||
|
ok := false // A flag to ensure the Catch block is only executed once.
|
||||||
|
|
||||||
|
// If a Catch block is provided, defer a function that recovers from panics.
|
||||||
|
// The recovery will invoke the Catch block if a panic occurs.
|
||||||
|
if c.Catch != nil {
|
||||||
|
defer func(done *bool) {
|
||||||
|
if !(*done) { // Ensure the Catch block is only executed once.
|
||||||
|
if rc := recover(); rc != nil { // If a panic occurred, handle it.
|
||||||
|
c.Catch(*NewErrPanic(ToError(rc))) // Pass the recovered value (converted to error) to the Catch block.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}(&ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the Try block.
|
||||||
|
c.Try(params...)
|
||||||
|
|
||||||
|
// Mark the flag as true to indicate the Try block has completed without triggering a panic.
|
||||||
|
ok = true
|
||||||
|
}
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package errs
|
||||||
|
|
||||||
|
// Unwrapper is an interface that defines the method Unwrap.
|
||||||
|
// The Unwrap method should return the underlying error that is wrapped by the type implementing this interface.
|
||||||
|
type Unwrapper interface {
|
||||||
|
Unwrap() error
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnwrapperFnc is a function type that implements the Unwrapper interface.
|
||||||
|
// It is a function that returns an error when called.
|
||||||
|
type UnwrapperFnc func() error
|
||||||
|
|
||||||
|
// Unwrap implements the Unwrapper interface for the UnwrapperFnc type.
|
||||||
|
// It invokes the function f and returns the error that the function returns.
|
||||||
|
func (f UnwrapperFnc) Unwrap() error {
|
||||||
|
return f() // Call the function and return its error result.
|
||||||
|
}
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package errs
|
||||||
|
|
||||||
|
// UnwrapperList is an interface that defines the method Unwrap.
|
||||||
|
// The Unwrap method should return a slice of errors (i.e., []error) that are wrapped by the type implementing this interface.
|
||||||
|
type UnwrapperList interface {
|
||||||
|
Unwrap() []error
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnwrapperListFnc is a function type that implements the UnwrapperList interface.
|
||||||
|
// It is a function that returns a slice of errors when called.
|
||||||
|
type UnwrapperListFnc func() []error
|
||||||
|
|
||||||
|
// Unwrap implements the UnwrapperList interface for the UnwrapperListFnc type.
|
||||||
|
// It invokes the function f and returns the slice of errors that the function returns.
|
||||||
|
func (f UnwrapperListFnc) Unwrap() []error {
|
||||||
|
return f() // Call the function and return its slice of error results.
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
module core
|
||||||
|
|
||||||
|
go 1.22
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package g_maks
|
||||||
|
|
||||||
|
import "core/errs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
moduleName = "core.pods.maks" + errs.ModuleSeparator
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
G = struct {
|
||||||
|
ErrKeyNotFound,
|
||||||
|
ErrBadKeys,
|
||||||
|
ErrDuplicatedKey errs.ErrCode
|
||||||
|
}{
|
||||||
|
|
||||||
|
ErrBadKeys: errs.MakeErrCode(moduleName + "bad-keys"),
|
||||||
|
ErrKeyNotFound: errs.MakeErrCode(moduleName + "key-not-found"),
|
||||||
|
ErrDuplicatedKey: errs.MakeErrCode(moduleName + "duplicated-key"),
|
||||||
|
}
|
||||||
|
)
|
||||||
@ -0,0 +1,284 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package g_maks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GMak2 is a generic structure that supports two indices for fast lookups.
|
||||||
|
// - T represents the type of data stored.
|
||||||
|
// - I1 and I2 are the types for the two indices (must be comparable).
|
||||||
|
type (
|
||||||
|
GMak2[T any, I1, I2 comparable] struct {
|
||||||
|
entries []gEntry2k[T, I1, I2] // Data slice storing all elements.
|
||||||
|
free []int // List of free positions for recycling.
|
||||||
|
zero T // A zero value of the generic type to reset data.
|
||||||
|
map1 map[I1]int // Map for the first key to the position in the data slice.
|
||||||
|
map2 map[I2]int // Map for the second key to the position in the data slice.
|
||||||
|
}
|
||||||
|
|
||||||
|
// gEntry2k holds the data and associated keys for the entries in GMak2.
|
||||||
|
gEntry2k[T any, I1, I2 any] struct {
|
||||||
|
data T // The data associated with this entry.
|
||||||
|
key1 I1 // The first key used for indexing.
|
||||||
|
key2 I2 // The second key used for indexing.
|
||||||
|
isFree bool
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewGMak2 creates a new instance of GMak2 with initialized maps.
|
||||||
|
func NewGMak2[T any, I1, I2 comparable]() *GMak2[T, I1, I2] {
|
||||||
|
return &GMak2[T, I1, I2]{
|
||||||
|
map1: make(map[I1]int),
|
||||||
|
map2: make(map[I2]int),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasKey1 checks if the first key exists in map1.
|
||||||
|
func (m *GMak2[_, I1, I2]) HasKey1(key I1) bool {
|
||||||
|
_, exists := m.map1[key]
|
||||||
|
return exists
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasKey2 checks if the second key exists in map2.
|
||||||
|
func (m *GMak2[_, I1, I2]) HasKey2(key I2) bool {
|
||||||
|
_, exists := m.map2[key]
|
||||||
|
return exists
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasKeys checks if both keys exist in the respective maps.
|
||||||
|
func (m *GMak2[_, I1, I2]) HasKeys(key1 I1, key2 I2) bool {
|
||||||
|
_, h1 := m.map1[key1]
|
||||||
|
_, h2 := m.map2[key2]
|
||||||
|
return h1 && h2
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add inserts a new element into the GMak2 structure, associating it with the provided keys.
|
||||||
|
func (m *GMak2[T, I1, I2]) Add(data T, key1 I1, key2 I2) error {
|
||||||
|
if m.HasKeys(key1, key2) {
|
||||||
|
return G.ErrDuplicatedKey // Error if the keys already exist.
|
||||||
|
}
|
||||||
|
return m.add(data, key1, key2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// add adds the data to the structure, either reusing a free position or appending to the entries slice.
|
||||||
|
func (m *GMak2[T, I1, I2]) add(data T, key1 I1, key2 I2) error {
|
||||||
|
var pos int
|
||||||
|
if len(m.free) > 0 {
|
||||||
|
// Reuse a free position from the free list.
|
||||||
|
pos = m.free[len(m.free)-1]
|
||||||
|
m.free = m.free[:len(m.free)-1] // Remove the last free position.
|
||||||
|
m.entries[pos].data = data
|
||||||
|
m.entries[pos].key1 = key1
|
||||||
|
m.entries[pos].key2 = key2
|
||||||
|
m.entries[pos].isFree = false
|
||||||
|
} else {
|
||||||
|
// If no free positions, append a new entry to the entries slice.
|
||||||
|
pos = len(m.entries)
|
||||||
|
m.entries = append(m.entries, gEntry2k[T, I1, I2]{
|
||||||
|
data: data,
|
||||||
|
key1: key1,
|
||||||
|
key2: key2,
|
||||||
|
isFree: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map the keys to the corresponding position in the entries slice.
|
||||||
|
m.map1[key1] = pos
|
||||||
|
m.map2[key2] = pos
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetByKey1 retrieves the data associated with the first key.
|
||||||
|
func (m *GMak2[T, I1, I2]) GetByKey1(key I1) (T, bool) {
|
||||||
|
pos, exists := m.map1[key]
|
||||||
|
if !exists {
|
||||||
|
return m.zero, false
|
||||||
|
}
|
||||||
|
return m.entries[pos].data, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetByKey2 retrieves the data associated with the second key.
|
||||||
|
func (m *GMak2[T, I1, I2]) GetByKey2(key I2) (T, bool) {
|
||||||
|
pos, exists := m.map2[key]
|
||||||
|
if !exists {
|
||||||
|
return m.zero, false
|
||||||
|
}
|
||||||
|
return m.entries[pos].data, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// DelByKey1 removes an element by the first key and frees the position for reuse.
|
||||||
|
func (m *GMak2[T, I1, I2]) DelByKey1(key I1) error {
|
||||||
|
pos, has := m.map1[key]
|
||||||
|
if !has {
|
||||||
|
return G.ErrKeyNotFound // Error if the key is not found.
|
||||||
|
}
|
||||||
|
m.del(pos) // Perform the deletion and free the position.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DelByKey2 removes an element by the second key and frees the position for reuse.
|
||||||
|
func (m *GMak2[T, I1, I2]) DelByKey2(key I2) error {
|
||||||
|
pos, has := m.map2[key]
|
||||||
|
if !has {
|
||||||
|
return G.ErrKeyNotFound // Error if the key is not found.
|
||||||
|
}
|
||||||
|
m.del(pos) // Perform the deletion and free the position.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// del deletes an entry by position and frees up the space for reuse.
|
||||||
|
func (m *GMak2[T, I1, I2]) del(pos int) {
|
||||||
|
m.free = append(m.free, pos) // Add the position to the free list.
|
||||||
|
delete(m.map1, m.entries[pos].key1) // Remove the first key from map1.
|
||||||
|
delete(m.map2, m.entries[pos].key2) // Remove the second key from map2.
|
||||||
|
m.entries[pos].data = m.zero // Reset the data to the zero value.
|
||||||
|
m.entries[pos].isFree = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetByKey1 updates the data associated with the first key.
|
||||||
|
func (m *GMak2[T, I1, I2]) SetByKey1(key I1, newData T) error {
|
||||||
|
pos, exists := m.map1[key]
|
||||||
|
if !exists {
|
||||||
|
return G.ErrKeyNotFound // Error if the key is not found.
|
||||||
|
}
|
||||||
|
m.entries[pos].data = newData
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetByKey2 updates the data associated with the second key.
|
||||||
|
func (m *GMak2[T, I1, I2]) SetByKey2(key I2, newData T) error {
|
||||||
|
pos, exists := m.map2[key]
|
||||||
|
if !exists {
|
||||||
|
return G.ErrKeyNotFound // Error if the key is not found.
|
||||||
|
}
|
||||||
|
m.entries[pos].data = newData
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetOrAdd inserts a new element or updates the existing element if both keys are already present.
|
||||||
|
func (m *GMak2[T, I1, I2]) SetOrAdd(data T, key1 I1, key2 I2) error {
|
||||||
|
// Check if either key1 or key2 already exists in the respective maps
|
||||||
|
p1, h1 := m.map1[key1]
|
||||||
|
p2, h2 := m.map2[key2]
|
||||||
|
|
||||||
|
if !h1 && !h2 {
|
||||||
|
return m.add(data, key1, key2)
|
||||||
|
}
|
||||||
|
if p1 != p2 {
|
||||||
|
return G.ErrBadKeys // Error if keys point to different positions.
|
||||||
|
}
|
||||||
|
m.entries[p1].data = data
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate iterates through all entries and applies the provided function to each entry.
|
||||||
|
func (m *GMak2[T, I1, I2]) Iterate(fn func(data T, key1 I1, key2 I2) bool) {
|
||||||
|
for _, entry := range m.entries {
|
||||||
|
if entry.isFree {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !fn(entry.data, entry.key1, entry.key2) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset clears all entries, maps, and free positions in the GMak2 structure.
|
||||||
|
// This function is useful for reinitializing the GMak2 structure without creating a new instance.
|
||||||
|
func (m *GMak2[_, _, _]) Reset() {
|
||||||
|
// Iterate through all entries and delete their associated keys from the maps.
|
||||||
|
for _, d := range m.entries {
|
||||||
|
delete(m.map1, d.key1)
|
||||||
|
delete(m.map2, d.key2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the free list and the entries slice.
|
||||||
|
m.free = m.free[:0] // Clear the free positions list.
|
||||||
|
m.entries = m.entries[:0] // Clear the entries slice.
|
||||||
|
}
|
||||||
|
|
||||||
|
// compact removes free entries by moving valid entries to the beginning of the slice.
|
||||||
|
func (m *GMak2[T, I1, I2]) compact() {
|
||||||
|
writeIndex := 0 // Posición donde escribir la próxima entrada válida.
|
||||||
|
|
||||||
|
for readIndex := 0; readIndex < len(m.entries); readIndex++ {
|
||||||
|
entry := m.entries[readIndex]
|
||||||
|
if !entry.isFree {
|
||||||
|
// Mover entrada válida hacia adelante si es necesario.
|
||||||
|
if writeIndex != readIndex {
|
||||||
|
m.entries[writeIndex] = entry
|
||||||
|
}
|
||||||
|
writeIndex++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reducir el slice al tamaño compactado.
|
||||||
|
m.entries = m.entries[:writeIndex]
|
||||||
|
m.free = m.free[:0] // All free positions are cleared.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compact removes free entries by moving valid entries to the beginning of the slice.
|
||||||
|
// It updates the maps to reflect the new positions.
|
||||||
|
func (m *GMak2[T, I1, I2]) Compact() {
|
||||||
|
m.compact()
|
||||||
|
m.rebuildMaps()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SortByKey1 sorts the entries based on the provided comparison function for key1.
|
||||||
|
// The `less` function determines the ordering between two keys of type I1.
|
||||||
|
func (m *GMak2[T, I1, I2]) SortByKey1(less func(key1, key2 I1) bool) {
|
||||||
|
m.compact()
|
||||||
|
sort.SliceStable(m.entries, func(i, j int) bool {
|
||||||
|
return less(m.entries[i].key1, m.entries[j].key1)
|
||||||
|
})
|
||||||
|
m.rebuildMaps()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SortByKey2 sorts the entries based on the provided comparison function for key2.
|
||||||
|
// The `less` function determines the ordering between two keys of type I2.
|
||||||
|
func (m *GMak2[T, I1, I2]) SortByKey2(less func(key1, key2 I2) bool) {
|
||||||
|
m.compact()
|
||||||
|
sort.SliceStable(m.entries, func(i, j int) bool {
|
||||||
|
return less(m.entries[i].key2, m.entries[j].key2)
|
||||||
|
})
|
||||||
|
m.rebuildMaps()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to update maps after sorting.
|
||||||
|
func (m *GMak2[_, I1, I2]) rebuildMaps() {
|
||||||
|
// Rebuild the maps to reflect the new positions of keys.
|
||||||
|
m.map1 = make(map[I1]int)
|
||||||
|
m.map2 = make(map[I2]int)
|
||||||
|
for i, entry := range m.entries {
|
||||||
|
if !entry.isFree {
|
||||||
|
m.map1[entry.key1] = i
|
||||||
|
m.map2[entry.key2] = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package scps
|
||||||
|
|
||||||
|
import (
|
||||||
|
"core/errs"
|
||||||
|
"core/rets"
|
||||||
|
)
|
||||||
|
|
||||||
|
// moduleName defines the unique identifier for this module in the error system.
|
||||||
|
// It uses the standardized module separator from the errs package.
|
||||||
|
const moduleName = "core.scps" + errs.ModuleSeparator
|
||||||
|
|
||||||
|
// G exports public error codes for the module.
|
||||||
|
// This struct provides centralized access to all error codes that can be
|
||||||
|
// used by other packages and external code.
|
||||||
|
//
|
||||||
|
// Error codes include:
|
||||||
|
// - ErrKeyNotFound: When a requested key doesn't exist in the scope
|
||||||
|
// - ErrInvalidKey: When a key is nil or otherwise invalid
|
||||||
|
// - ErrInvalidValue: When attempting to store an invalid value
|
||||||
|
// - ErrReadOnlyScope: When attempting to modify a read-only scope
|
||||||
|
var (
|
||||||
|
G = struct {
|
||||||
|
ErrKeyNotFound,
|
||||||
|
ErrInvalidKey,
|
||||||
|
ErrInvalidValue,
|
||||||
|
ErrReadOnlyScope errs.ErrCode
|
||||||
|
}{
|
||||||
|
ErrKeyNotFound: errs.MakeErrCode(moduleName + "key-not-found"),
|
||||||
|
ErrInvalidKey: errs.MakeErrCode(moduleName + "invalid-key"),
|
||||||
|
ErrInvalidValue: errs.MakeErrCode(moduleName + "invalid-value"),
|
||||||
|
ErrReadOnlyScope: errs.MakeErrCode(moduleName + "read-only-store"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// g provides package-private result instances for common error conditions.
|
||||||
|
// These are pre-created for efficiency and consistency in error handling
|
||||||
|
// throughout the package.
|
||||||
|
g = struct {
|
||||||
|
ResultKeyNotFound,
|
||||||
|
ResultInvalidKey,
|
||||||
|
ResultInvalidValue,
|
||||||
|
ResultReadOnly rets.Result
|
||||||
|
}{
|
||||||
|
ResultKeyNotFound: rets.NewErrorResult(G.ErrKeyNotFound),
|
||||||
|
ResultInvalidKey: rets.NewErrorResult(G.ErrInvalidKey),
|
||||||
|
ResultInvalidValue: rets.NewErrorResult(G.ErrInvalidValue),
|
||||||
|
ResultReadOnly: rets.NewErrorResult(G.ErrReadOnlyScope),
|
||||||
|
}
|
||||||
|
)
|
||||||
@ -0,0 +1,248 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package scps
|
||||||
|
|
||||||
|
// Package scope provides a hierarchical key-value store implementation with thread-safety
|
||||||
|
// and parent-child relationship support. It allows for creating isolated scopes that can
|
||||||
|
// inherit values from parent scopes while maintaining their own independent modifications.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"core/rets"
|
||||||
|
"core/vals"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
// Scope represents a hierarchical key-value store with thread-safe operations.
|
||||||
|
// Each Scope can have a parent from which it inherits values, and can be marked
|
||||||
|
// as read-only to prevent modifications.
|
||||||
|
Scope struct {
|
||||||
|
// parent represents the parent scope from which this scope inherits values
|
||||||
|
parent vals.KeyValueGetter
|
||||||
|
// entries stores the key-value pairs in a thread-safe map
|
||||||
|
entries sync.Map
|
||||||
|
// isReadOnly indicates whether the scope can be modified
|
||||||
|
isReadOnly bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// ScopeFnc defines a function type for scope configuration operations.
|
||||||
|
// It's used in the functional options pattern for configuring new scopes.
|
||||||
|
ScopeFnc func(*Scope) error
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewScope creates a new Scope instance with an optional parent and configuration options.
|
||||||
|
// It initializes an empty scope and applies the provided configuration functions in order.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - parent: The parent scope from which the new scope will inherit values (can be nil)
|
||||||
|
// - ops: Optional configuration functions to be applied to the new scope
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - *Scope: The newly created scope
|
||||||
|
// - error: An error if any configuration operation fails
|
||||||
|
func NewScope(parent vals.KeyValueGetter, ops ...ScopeFnc) (*Scope, error) {
|
||||||
|
sc := &Scope{
|
||||||
|
parent: parent,
|
||||||
|
entries: sync.Map{},
|
||||||
|
}
|
||||||
|
for _, op := range ops {
|
||||||
|
if er := op(sc); er != nil {
|
||||||
|
return nil, er
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsReadOnly returns whether the scope is in read-only mode.
|
||||||
|
// Read-only scopes cannot be modified through SetValue, DelValue, or Reset operations.
|
||||||
|
func (s *Scope) IsReadOnly() bool { return s.isReadOnly }
|
||||||
|
|
||||||
|
// NewChild creates a new child Scope inheriting from the current Scope.
|
||||||
|
// The child Scope can have its own independent key-value pairs and optional configurations.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - ops: Optional configuration functions to be applied to the child scope
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - *Scope: The newly created child scope
|
||||||
|
// - error: An error if creation or configuration fails
|
||||||
|
func (s *Scope) NewChild(ops ...ScopeFnc) (*Scope, error) {
|
||||||
|
sc, er := NewScope(s, ops...)
|
||||||
|
if er != nil {
|
||||||
|
return nil, er
|
||||||
|
}
|
||||||
|
return sc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DelValue removes a key-value pair from the current Scope by its key.
|
||||||
|
// If the Scope is marked as read-only, the operation returns an error.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - key: The key to remove from the scope
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - error: ErrReadOnlyScope if the scope is read-only, nil otherwise
|
||||||
|
func (s *Scope) DelValue(key any) error {
|
||||||
|
if s.IsReadOnly() {
|
||||||
|
// No modifications allowed if the Scope is read-only.
|
||||||
|
return G.ErrReadOnlyScope
|
||||||
|
}
|
||||||
|
s.entries.Delete(key) // Delete the key-value pair.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetValue retrieves a value from the scope by its key.
|
||||||
|
// If the key is not found in the current scope and a parent exists,
|
||||||
|
// the request is delegated to the parent scope.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - key: The key to look up
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - rets.Resulter: A result containing the value if found, or an error result if:
|
||||||
|
// - The key is nil (ResultInvalidKey)
|
||||||
|
// - The key is not found in this scope or any parent scope (ResultKeyNotFound)
|
||||||
|
func (s *Scope) GetValue(key any) rets.Result {
|
||||||
|
if key == nil {
|
||||||
|
return g.ResultInvalidKey
|
||||||
|
}
|
||||||
|
if en, ok := s.entries.Load(key); ok {
|
||||||
|
return (en.(scopeEntry)).Result()
|
||||||
|
}
|
||||||
|
if s.parent != nil {
|
||||||
|
return s.parent.GetValue(key)
|
||||||
|
}
|
||||||
|
return g.ResultKeyNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetValue stores a key-value pair in the current scope.
|
||||||
|
// If the scope is read-only or the key is nil, an error is returned.
|
||||||
|
// If the key already exists and is associated with a provider, the operation fails.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - key: The key under which to store the value
|
||||||
|
// - value: The value to store
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - error: An error if:
|
||||||
|
// - The key is nil (ErrInvalidKey)
|
||||||
|
// - The scope is read-only (ErrReadOnlyScope)
|
||||||
|
// - The key exists and is associated with a provider (ErrInvalidValue)
|
||||||
|
func (s *Scope) SetValue(key, value any) error {
|
||||||
|
var en scopeEntry
|
||||||
|
if key == nil {
|
||||||
|
return G.ErrInvalidKey
|
||||||
|
}
|
||||||
|
if s.isReadOnly {
|
||||||
|
return G.ErrReadOnlyScope
|
||||||
|
}
|
||||||
|
if ob, ok := s.entries.Load(key); ok {
|
||||||
|
en = ob.(scopeEntry)
|
||||||
|
if !en.isValue {
|
||||||
|
// si es un provider no podemos cambiarlo una vez
|
||||||
|
// establecido el valor como un valor simple
|
||||||
|
//
|
||||||
|
return G.ErrInvalidValue
|
||||||
|
}
|
||||||
|
//
|
||||||
|
en.value = value
|
||||||
|
} else {
|
||||||
|
en = *newScopeEntry(value)
|
||||||
|
}
|
||||||
|
s.entries.Store(key, en)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Range iterates over all key-value pairs in the current Scope.
|
||||||
|
// For each pair, it invokes the provided function with the key and value.
|
||||||
|
// The iteration stops if the function returns false.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - fnc: A function that receives each key-value pair and returns whether to continue iteration
|
||||||
|
func (s *Scope) Range(fnc func(key, value any) bool) {
|
||||||
|
s.entries.Range(func(key, value any) bool {
|
||||||
|
entry := value.(scopeEntry)
|
||||||
|
if entry.isValue {
|
||||||
|
return fnc(key, entry.value)
|
||||||
|
}
|
||||||
|
return fnc(key, entry.provider.Value())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset clears all key-value pairs from the current Scope.
|
||||||
|
// If the Scope is marked as read-only, the operation returns an error.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - error: ErrReadOnlyScope if the scope is read-only, nil otherwise
|
||||||
|
func (s *Scope) Reset() error {
|
||||||
|
if s.isReadOnly {
|
||||||
|
return G.ErrReadOnlyScope // No modifications allowed if the Scope is read-only.
|
||||||
|
}
|
||||||
|
s.entries.Range(func(k, _ any) bool {
|
||||||
|
s.entries.Delete(k) // Delete each key-value pair.
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ScopeWithReadOnly returns a ScopeFnc that sets the scope to read-only mode.
|
||||||
|
// Once applied, the scope will not allow any modifications to its values.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - ScopeFnc: A function that when called will mark the scope as read-only
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// scope, _ := NewScope(ScopeWithReadOnly())
|
||||||
|
// // scope is now read-only
|
||||||
|
func ScopeWithReadOnly() ScopeFnc {
|
||||||
|
return func(s *Scope) error {
|
||||||
|
s.isReadOnly = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ScopeWithValue returns a ScopeFnc that sets an initial key-value pair in the scope.
|
||||||
|
// This function is used during scope creation to initialize the scope with values.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - key: The key under which to store the value (can be of any type)
|
||||||
|
// - value: The value to store (can be of any type)
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - ScopeFnc: A function that when called will set the specified key-value pair
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// scope, _ := NewScope(ScopeWithValue("key", "value"))
|
||||||
|
// // scope now contains "key":"value"
|
||||||
|
func ScopeWithValue(key, value any) ScopeFnc {
|
||||||
|
return func(s *Scope) error {
|
||||||
|
return s.SetValue(key, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,91 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package scps
|
||||||
|
|
||||||
|
import (
|
||||||
|
"core/rets"
|
||||||
|
"core/vals"
|
||||||
|
)
|
||||||
|
|
||||||
|
// scopeEntry represents a value stored in a Scope, which can be either
|
||||||
|
// a direct value or a value provider. This type handles the dual nature
|
||||||
|
// of scope values, allowing for both static values and dynamic value generation.
|
||||||
|
type (
|
||||||
|
scopeEntry struct {
|
||||||
|
// isValue indicates whether the entry contains a direct value (true)
|
||||||
|
// or a value provider (false)
|
||||||
|
isValue bool
|
||||||
|
|
||||||
|
// value stores the actual value when isValue is true
|
||||||
|
// This field is used for direct value storage
|
||||||
|
value any
|
||||||
|
|
||||||
|
// provider stores a ValueProvider interface when isValue is false
|
||||||
|
// This field is used for dynamic value generation
|
||||||
|
provider vals.ValueProvider
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// newScopeEntry creates a new scopeEntry instance based on the provided value.
|
||||||
|
// It automatically determines whether the value is a direct value or a value provider.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - value: The value to store, which can be either a direct value or a ValueProvider
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - *scopeEntry: A new scope entry configured according to the value type
|
||||||
|
//
|
||||||
|
// The function checks if the provided value implements the ValueProvider interface.
|
||||||
|
// If it does, the entry is configured to use the provider; otherwise, it stores
|
||||||
|
// the value directly.
|
||||||
|
func newScopeEntry(value any) *scopeEntry {
|
||||||
|
pr, is := vals.CheckValueProvider(value)
|
||||||
|
if is {
|
||||||
|
return &scopeEntry{provider: pr}
|
||||||
|
}
|
||||||
|
return &scopeEntry{
|
||||||
|
value: value,
|
||||||
|
isValue: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Result returns the entry's value wrapped in a Resulter interface.
|
||||||
|
// For direct values, it returns the stored value directly.
|
||||||
|
// For providers, it returns the value obtained by calling the provider's Value() method.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - rets.Resulter: A result containing either the direct value or the provider's generated value
|
||||||
|
//
|
||||||
|
// The returned Resulter will contain:
|
||||||
|
// - For direct values: the stored value wrapped in a ValueResult
|
||||||
|
// - For providers: the result of calling Value() on the provider wrapped in a ValueResult
|
||||||
|
func (e scopeEntry) Result() rets.Result {
|
||||||
|
if e.isValue {
|
||||||
|
return rets.ValueResult{V: e.value}
|
||||||
|
}
|
||||||
|
return rets.ValueResult{V: e.provider.Value()}
|
||||||
|
}
|
||||||
@ -0,0 +1,144 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package g_sets
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
|
// GSafeSet provides a thread-safe wrapper around GSet, implementing synchronized
|
||||||
|
// access to all set operations through read-write mutex locks.
|
||||||
|
//
|
||||||
|
// Type Parameters:
|
||||||
|
// - T: Any comparable type that can be used as set elements
|
||||||
|
//
|
||||||
|
// The struct ensures thread-safe access to the underlying GSet by:
|
||||||
|
// - Using RWMutex for optimized read/write operations
|
||||||
|
// - Providing exclusive locks for modifications
|
||||||
|
// - Allowing concurrent reads with read locks
|
||||||
|
type GSafeSet[T comparable] struct {
|
||||||
|
// mux provides mutual exclusion for thread-safe operations
|
||||||
|
mux sync.RWMutex
|
||||||
|
// inner holds the actual set implementation
|
||||||
|
inner *GSet[T]
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGSafeSet creates and initializes a new thread-safe set.
|
||||||
|
//
|
||||||
|
// Type Parameters:
|
||||||
|
// - T: The type of elements the set will contain
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - *GSafeSet[T]: A pointer to a new, initialized thread-safe set
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// safeSet := NewGSafeSet[string]()
|
||||||
|
func NewGSafeSet[T comparable]() *GSafeSet[T] {
|
||||||
|
return &GSafeSet[T]{inner: NewGSet[T]()}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Has checks if a value exists in the set using a read lock.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - value: The element to check for existence
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - bool: true if the value exists in the set, false otherwise
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// set := NewGSafeSet[int]()
|
||||||
|
// set.Add(1)
|
||||||
|
// exists := set.Has(1) // true
|
||||||
|
func (s *GSafeSet[T]) Has(value T) (rs bool) {
|
||||||
|
s.mux.RLock()
|
||||||
|
rs = s.inner.Has(value)
|
||||||
|
s.mux.RUnlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add inserts a new value into the set if it doesn't already exist.
|
||||||
|
// Uses a write lock to ensure thread-safe modification.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - value: The element to add to the set
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - bool: true if the value was added, false if it already existed
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// set := NewGSafeSet[string]()
|
||||||
|
// added := set.Add("hello") // true
|
||||||
|
// added = set.Add("hello") // false, already exists
|
||||||
|
func (s *GSafeSet[T]) Add(value T) (rs bool) {
|
||||||
|
s.mux.Lock()
|
||||||
|
rs = s.inner.Add(value)
|
||||||
|
s.mux.Unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Del removes a value from the set if it exists.
|
||||||
|
// Uses a write lock to ensure thread-safe modification.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - value: The element to remove from the set
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - bool: true if the value was removed, false if it didn't exist
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// set := NewGSafeSet[int]()
|
||||||
|
// set.Add(42)
|
||||||
|
// removed := set.Del(42) // true
|
||||||
|
// removed = set.Del(42) // false, doesn't exist
|
||||||
|
func (s *GSafeSet[T]) Del(value T) (rs bool) {
|
||||||
|
s.mux.Lock()
|
||||||
|
rs = s.inner.Del(value)
|
||||||
|
s.mux.Unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// List returns a slice containing all elements in the set.
|
||||||
|
// Uses a read lock since it doesn't modify the set.
|
||||||
|
// The order of elements in the returned slice is not guaranteed.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - []T: A slice containing all elements currently in the set
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// set := NewGSafeSet[string]()
|
||||||
|
// set.Add("a")
|
||||||
|
// set.Add("b")
|
||||||
|
// elements := set.List() // []string{"a", "b"} (order not guaranteed)
|
||||||
|
func (s *GSafeSet[T]) List() (rs []T) {
|
||||||
|
s.mux.RLock()
|
||||||
|
rs = s.inner.List()
|
||||||
|
s.mux.RUnlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
@ -0,0 +1,131 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package g_sets
|
||||||
|
|
||||||
|
// GSet implements a generic set data structure using a map with empty structs as values.
|
||||||
|
// This implementation provides memory-efficient storage of unique elements of any comparable type.
|
||||||
|
//
|
||||||
|
// Type Parameters:
|
||||||
|
// - T: Any comparable type that can be used as set elements
|
||||||
|
//
|
||||||
|
// The underlying map[T]struct{} representation ensures:
|
||||||
|
// - O(1) average time complexity for all operations
|
||||||
|
// - Minimal memory overhead by using empty structs as values
|
||||||
|
type GSet[T comparable] map[T]struct{}
|
||||||
|
|
||||||
|
// NewGSet creates and initializes a new empty set.
|
||||||
|
//
|
||||||
|
// Type Parameters:
|
||||||
|
// - T: The type of elements the set will contain
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - *GSet[T]: A pointer to a new, initialized empty set
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// set := NewGSet[string]()
|
||||||
|
func NewGSet[T comparable]() *GSet[T] {
|
||||||
|
s := make(GSet[T])
|
||||||
|
return &s
|
||||||
|
}
|
||||||
|
|
||||||
|
// Has checks if a value exists in the set.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - value: The element to check for existence
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - bool: true if the value exists in the set, false otherwise
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// set := NewGSet[int]()
|
||||||
|
// set.Add(1)
|
||||||
|
// exists := set.Has(1) // true
|
||||||
|
func (s *GSet[T]) Has(value T) bool {
|
||||||
|
_, h := (*s)[value]
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add inserts a new value into the set if it doesn't already exist.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - value: The element to add to the set
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - bool: true if the value was added, false if it already existed
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// set := NewGSet[string]()
|
||||||
|
// added := set.Add("hello") // true
|
||||||
|
// added = set.Add("hello") // false, already exists
|
||||||
|
func (s *GSet[T]) Add(value T) bool {
|
||||||
|
l := len(*s)
|
||||||
|
(*s)[value] = struct{}{}
|
||||||
|
return l != len(*s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Del removes a value from the set if it exists.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - value: The element to remove from the set
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - bool: true if the value was removed, false if it didn't exist
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// set := NewGSet[int]()
|
||||||
|
// set.Add(42)
|
||||||
|
// removed := set.Del(42) // true
|
||||||
|
// removed = set.Del(42) // false, doesn't exist
|
||||||
|
func (s *GSet[T]) Del(value T) bool {
|
||||||
|
l := len(*s)
|
||||||
|
delete(*s, value)
|
||||||
|
return l != len(*s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// List returns a slice containing all elements in the set.
|
||||||
|
// The order of elements in the returned slice is not guaranteed.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - []T: A slice containing all elements currently in the set
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// set := NewGSet[string]()
|
||||||
|
// set.Add("a")
|
||||||
|
// set.Add("b")
|
||||||
|
// elements := set.List() // []string{"a", "b"} (order not guaranteed)
|
||||||
|
func (s *GSet[T]) List() []T {
|
||||||
|
l := make([]T, len(*s))
|
||||||
|
for k := range *s {
|
||||||
|
l = append(l, k)
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package g_sets
|
||||||
|
|
||||||
|
// GSeter represents a generic set interface that works with any comparable type.
|
||||||
|
// It provides basic set operations like adding, removing, checking membership,
|
||||||
|
// and listing elements.
|
||||||
|
//
|
||||||
|
// Type Parameters:
|
||||||
|
// - T: Any comparable type that can be used as set elements.
|
||||||
|
// The comparable constraint ensures that values can be compared for equality.
|
||||||
|
//
|
||||||
|
// The interface ensures that implementations provide thread-safe operations
|
||||||
|
// for managing a collection of unique elements of type T.
|
||||||
|
type GSeter[T comparable] interface {
|
||||||
|
// Has checks if the given value exists in the set.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - value: The element to check for membership
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - bool: true if the value exists in the set, false otherwise
|
||||||
|
Has(value T) bool
|
||||||
|
|
||||||
|
// Add inserts a new value into the set if it doesn't already exist.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - value: The element to add to the set
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - bool: true if the value was added, false if it already existed
|
||||||
|
Add(value T) bool
|
||||||
|
|
||||||
|
// Del removes a value from the set if it exists.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - value: The element to remove from the set
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - bool: true if the value was removed, false if it didn't exist
|
||||||
|
Del(value T) bool
|
||||||
|
|
||||||
|
// List returns a slice containing all elements in the set.
|
||||||
|
// The order of elements in the returned slice is not guaranteed.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - []T: A slice containing all elements currently in the set
|
||||||
|
List() []T
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example usage:
|
||||||
|
//
|
||||||
|
// type StringSet struct {
|
||||||
|
// // implementation details
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Verify StringSet implements GSeter[string]
|
||||||
|
// var _ GSeter[string] = (*StringSet)(nil)
|
||||||
|
//
|
||||||
|
// func Example() {
|
||||||
|
// var set GSeter[string]
|
||||||
|
// set.Add("hello") // true
|
||||||
|
// set.Has("hello") // true
|
||||||
|
// set.Del("hello") // true
|
||||||
|
// set.List() // []string{}
|
||||||
|
// }
|
||||||
@ -0,0 +1,115 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package sets
|
||||||
|
|
||||||
|
import "core/pods/sets/g_sets"
|
||||||
|
|
||||||
|
// Package provides predefined type aliases for common set types
|
||||||
|
|
||||||
|
// Non-thread-safe set type aliases for primitive types
|
||||||
|
type (
|
||||||
|
// StringSet is a set of string values
|
||||||
|
StringSet = g_sets.GSet[string]
|
||||||
|
|
||||||
|
// BoolSet is a set of boolean values
|
||||||
|
BoolSet = g_sets.GSet[bool]
|
||||||
|
|
||||||
|
// Integer set types
|
||||||
|
|
||||||
|
// IntSet is a set of platform-dependent sized integers
|
||||||
|
IntSet = g_sets.GSet[int]
|
||||||
|
// Int8Set is a set of 8-bit integers
|
||||||
|
Int8Set = g_sets.GSet[int8]
|
||||||
|
// Int16Set is a set of 16-bit integers
|
||||||
|
Int16Set = g_sets.GSet[int16]
|
||||||
|
// Int32Set is a set of 32-bit integers
|
||||||
|
Int32Set = g_sets.GSet[int32]
|
||||||
|
// Int64Set is a set of 64-bit integers
|
||||||
|
Int64Set = g_sets.GSet[int64]
|
||||||
|
|
||||||
|
// Unsigned integer set types
|
||||||
|
|
||||||
|
// UintSet is a set of platform-dependent sized unsigned integers
|
||||||
|
UintSet = g_sets.GSet[uint]
|
||||||
|
// Uint8Set is a set of 8-bit unsigned integers
|
||||||
|
Uint8Set = g_sets.GSet[uint8]
|
||||||
|
// Uint16Set is a set of 16-bit unsigned integers
|
||||||
|
Uint16Set = g_sets.GSet[uint16]
|
||||||
|
// Uint32Set is a set of 32-bit unsigned integers
|
||||||
|
Uint32Set = g_sets.GSet[uint32]
|
||||||
|
// Uint64Set is a set of 64-bit unsigned integers
|
||||||
|
Uint64Set = g_sets.GSet[uint64]
|
||||||
|
|
||||||
|
// Floating-point set types
|
||||||
|
|
||||||
|
// Float32Set is a set of 32-bit floating-point numbers
|
||||||
|
Float32Set = g_sets.GSet[float32]
|
||||||
|
// Float64Set is a set of 64-bit floating-point numbers
|
||||||
|
Float64Set = g_sets.GSet[float64]
|
||||||
|
)
|
||||||
|
|
||||||
|
// Thread-safe set type aliases for primitive types
|
||||||
|
type (
|
||||||
|
// SafeStringSet is a thread-safe set of string values
|
||||||
|
SafeStringSet = g_sets.GSafeSet[string]
|
||||||
|
|
||||||
|
// SafeBoolSet is a thread-safe set of boolean values
|
||||||
|
SafeBoolSet = g_sets.GSafeSet[bool]
|
||||||
|
|
||||||
|
// Thread-safe integer set types
|
||||||
|
|
||||||
|
// SafeIntSet is a thread-safe set of platform-dependent sized integers
|
||||||
|
SafeIntSet = g_sets.GSafeSet[int]
|
||||||
|
// SafeInt8Set is a thread-safe set of 8-bit integers
|
||||||
|
SafeInt8Set = g_sets.GSafeSet[int8]
|
||||||
|
// SafeInt16Set is a thread-safe set of 16-bit integers
|
||||||
|
SafeInt16Set = g_sets.GSafeSet[int16]
|
||||||
|
// SafeInt32Set is a thread-safe set of 32-bit integers
|
||||||
|
SafeInt32Set = g_sets.GSafeSet[int32]
|
||||||
|
// SafeInt64Set is a thread-safe set of 64-bit integers
|
||||||
|
SafeInt64Set = g_sets.GSafeSet[int64]
|
||||||
|
|
||||||
|
// Thread-safe unsigned integer set types
|
||||||
|
|
||||||
|
// SafeUintSet is a thread-safe set of platform-dependent sized unsigned integers
|
||||||
|
SafeUintSet = g_sets.GSafeSet[uint]
|
||||||
|
// SafeUint8Set is a thread-safe set of 8-bit unsigned integers
|
||||||
|
SafeUint8Set = g_sets.GSafeSet[uint8]
|
||||||
|
// SafeUint16Set is a thread-safe set of 16-bit unsigned integers
|
||||||
|
SafeUint16Set = g_sets.GSafeSet[uint16]
|
||||||
|
// SafeUint32Set is a thread-safe set of 32-bit unsigned integers
|
||||||
|
SafeUint32Set = g_sets.GSafeSet[uint32]
|
||||||
|
// SafeUint64Set is a thread-safe set of 64-bit unsigned integers
|
||||||
|
SafeUint64Set = g_sets.GSafeSet[uint64]
|
||||||
|
|
||||||
|
// Thread-safe floating-point set types
|
||||||
|
|
||||||
|
// SafeFloat32Set is a thread-safe set of 32-bit floating-point numbers
|
||||||
|
SafeFloat32Set = g_sets.GSafeSet[float32]
|
||||||
|
// SafeFloat64Set is a thread-safe set of 64-bit floating-point numbers
|
||||||
|
SafeFloat64Set = g_sets.GSafeSet[float64]
|
||||||
|
)
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package rets
|
||||||
|
|
||||||
|
var (
|
||||||
|
|
||||||
|
// G provides a global set of predefined invalid values for various types.
|
||||||
|
// These values are useful as placeholders or defaults when representing invalid states.
|
||||||
|
// Each type has its corresponding `Invalid<Type>` structure to signify that the value is not valid.
|
||||||
|
G = struct {
|
||||||
|
NotValidString InvalidString
|
||||||
|
NotValidBool InvalidBool
|
||||||
|
|
||||||
|
NotValidInt InvalidInt
|
||||||
|
NotValidInt8 InvalidInt8
|
||||||
|
NotValidInt16 InvalidInt16
|
||||||
|
NotValidInt32 InvalidInt32
|
||||||
|
NotValidInt64 InvalidInt64
|
||||||
|
|
||||||
|
NotValidUint InvalidUint
|
||||||
|
NotValidUint8 InvalidUint8
|
||||||
|
NotValidUint16 InvalidUint16
|
||||||
|
NotValidUint32 InvalidUint32
|
||||||
|
NotValidUint64 InvalidUint64
|
||||||
|
|
||||||
|
NotValidFloat32 InvalidFloat32
|
||||||
|
NotValidFloat64 InvalidFloat64
|
||||||
|
|
||||||
|
NotValidComplex64 InvalidComplex64
|
||||||
|
NotValidComplex128 InvalidComplex128
|
||||||
|
}{
|
||||||
|
|
||||||
|
NotValidString: InvalidString{},
|
||||||
|
NotValidBool: InvalidBool{},
|
||||||
|
|
||||||
|
NotValidInt: InvalidInt{},
|
||||||
|
NotValidInt8: InvalidInt8{},
|
||||||
|
NotValidInt16: InvalidInt16{},
|
||||||
|
NotValidInt32: InvalidInt32{},
|
||||||
|
NotValidInt64: InvalidInt64{},
|
||||||
|
|
||||||
|
NotValidUint: InvalidUint{},
|
||||||
|
NotValidUint8: InvalidUint8{},
|
||||||
|
NotValidUint16: InvalidUint16{},
|
||||||
|
NotValidUint32: InvalidUint32{},
|
||||||
|
NotValidUint64: InvalidUint64{},
|
||||||
|
|
||||||
|
NotValidFloat32: InvalidFloat32{},
|
||||||
|
NotValidFloat64: InvalidFloat64{},
|
||||||
|
|
||||||
|
NotValidComplex64: InvalidComplex64{},
|
||||||
|
NotValidComplex128: InvalidComplex128{},
|
||||||
|
}
|
||||||
|
)
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package rets
|
||||||
|
|
||||||
|
import (
|
||||||
|
"core/rets/g_rets"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ErrorResult is an alias for the GErrorResult type from the g_rets package.
|
||||||
|
// This alias simplifies usage by referring to GErrorResult with the generic type `any`,
|
||||||
|
// making it easier to work with error results in the program.
|
||||||
|
type ErrorResult = g_rets.GErrorResult[any]
|
||||||
|
|
||||||
|
// NewErrorResult creates a new instance of ErrorResult using the g_rets package's NewGErrorResult function.
|
||||||
|
// It takes an error as input and returns a pointer to an ErrorResult containing that error.
|
||||||
|
//
|
||||||
|
// The function uses the `any` type for generic handling, allowing you to create error results
|
||||||
|
// for any specific type of error, even though the error itself is of the `error` type.
|
||||||
|
func NewErrorResult(err error) *ErrorResult {
|
||||||
|
// Create and return an error result using the provided error.
|
||||||
|
return g_rets.NewGErrorResult[any](err)
|
||||||
|
}
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package g_rets
|
||||||
|
|
||||||
|
import "core/errs"
|
||||||
|
|
||||||
|
// GErrorResult is a generic struct that represents an error result containing an error of type T.
|
||||||
|
// This type is used to encapsulate an error and indicates that the result is invalid.
|
||||||
|
type GErrorResult[T any] struct {
|
||||||
|
error // The error associated with the result.
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGErrorResult creates a new instance of GErrorResult with the given error.
|
||||||
|
// If the error is nil, it should handle the error appropriately (e.g., you may return a default error).
|
||||||
|
// It returns a pointer to a GErrorResult containing the provided error.
|
||||||
|
func NewGErrorResult[T any](err error) *GErrorResult[T] {
|
||||||
|
if err == nil {
|
||||||
|
// Valid Error is required, panic if is nil
|
||||||
|
panic(errs.G.ErrInvalidError)
|
||||||
|
}
|
||||||
|
return &GErrorResult[T]{err}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsValid returns false because GErrorResult represents an invalid result due to the error.
|
||||||
|
// This indicates that the result is not valid because it contains an error.
|
||||||
|
func (_ GErrorResult[T]) IsValid() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value returns nothing, as GErrorResult is considered invalid and has no valid value.
|
||||||
|
// This method can be used to indicate that there's no valid value associated with the error result.
|
||||||
|
func (_ GErrorResult[T]) Value() (zero T) {
|
||||||
|
// No valid value to return. This method could be modified to return a default or zero value
|
||||||
|
// if desired, but as it stands, it signifies that the result has no valid value due to the error.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Err returns the error associated with the result.
|
||||||
|
// This method allows access to the error wrapped in the GErrorResult.
|
||||||
|
func (r GErrorResult[T]) Err() error {
|
||||||
|
return r.error // Return the stored error
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package g_rets
|
||||||
|
|
||||||
|
// GResultor is a generic interface that extends the GValidator interface by
|
||||||
|
// adding the ability to handle errors alongside validation and value.
|
||||||
|
// It simplifies the return values of functions by combining the value,
|
||||||
|
// its validity status, and any potential error in one result.
|
||||||
|
//
|
||||||
|
// T represents the type of the value being returned.
|
||||||
|
// GResultor extends GValidator to include error handling.
|
||||||
|
// This interface combines validation, value retrieval, and error reporting
|
||||||
|
// into a single return value, making it useful for functions that may
|
||||||
|
// return a valid value or an error.
|
||||||
|
type GResultor[T any] interface {
|
||||||
|
// GValidator is the embedded interface that provides validation
|
||||||
|
// and value retrieval functionality.
|
||||||
|
GValidator[T]
|
||||||
|
|
||||||
|
// Err returns any error associated with the result.
|
||||||
|
// If there is an error, it will be returned; otherwise, it returns nil.
|
||||||
|
// This simplifies error handling by encapsulating both the value
|
||||||
|
// and error in a single result.
|
||||||
|
Err() error
|
||||||
|
}
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package g_rets
|
||||||
|
|
||||||
|
// GValidator is a generic interface designed to simplify function return values
|
||||||
|
// by combining both the value and a validity status into a single result.
|
||||||
|
//
|
||||||
|
// T represents the type of the value being returned.
|
||||||
|
type GValidator[T any] interface {
|
||||||
|
// IsValid checks if the value is valid.
|
||||||
|
// Returns true if the value is considered valid, otherwise false.
|
||||||
|
// This method simplifies the validation logic by returning just one result.
|
||||||
|
IsValid() bool
|
||||||
|
|
||||||
|
// Value returns the actual value of type T.
|
||||||
|
// This value is returned only if IsValid is true.
|
||||||
|
// It simplifies the function return by encapsulating both the value and its validity status.
|
||||||
|
Value() T
|
||||||
|
}
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package g_rets
|
||||||
|
|
||||||
|
// GValueResult is a generic struct that represents a valid result containing a value of type T.
|
||||||
|
// This type is used to encapsulate a valid value, indicating that the value is valid
|
||||||
|
// and that there is no error associated with it.
|
||||||
|
type GValueResult[T any] struct {
|
||||||
|
V T // The value of type T that is being wrapped in the result
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGValueResult creates a new instance of GValueResult with the given value.
|
||||||
|
// It returns a pointer to a GValueResult containing the value passed as an argument.
|
||||||
|
func NewGValueResult[T any](value T) *GValueResult[T] {
|
||||||
|
return &GValueResult[T]{V: value} // Initialize the struct with the provided value
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsValid returns true because GValueResult represents a valid result.
|
||||||
|
// It indicates that the value wrapped in the struct is considered valid.
|
||||||
|
func (_ GValueResult[T]) IsValid() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Err returns nil because GValueResult does not contain any errors.
|
||||||
|
// This method indicates that the result is valid and there is no associated error.
|
||||||
|
func (_ GValueResult[T]) Err() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value returns the value of type T that is stored inside the GValueResult.
|
||||||
|
// This method allows access to the actual value encapsulated by the result.
|
||||||
|
func (r GValueResult[T]) Value() T {
|
||||||
|
return r.V // Return the stored value
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package rets
|
||||||
|
|
||||||
|
import "core/rets/g_rets"
|
||||||
|
|
||||||
|
// Result is an alias for the GResultor type from the g_rets package with the generic type `any`.
|
||||||
|
// This alias is used to simplify working with function results that encapsulate a value
|
||||||
|
// and an error. By using `Result`, you can handle any type of value along with error information
|
||||||
|
// in a standardized way.
|
||||||
|
|
||||||
|
type Result = g_rets.GResultor[any]
|
||||||
@ -0,0 +1,214 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package rets
|
||||||
|
|
||||||
|
import "core/rets/g_rets"
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
// BoolResult represents a valid bool result.
|
||||||
|
BoolResult bool
|
||||||
|
|
||||||
|
// BoolError represents an invalid bool result with an error.
|
||||||
|
BoolError struct{ error }
|
||||||
|
|
||||||
|
// StringResult represents a valid string result.
|
||||||
|
StringResult string
|
||||||
|
|
||||||
|
// StringError represents an invalid string result with an error.
|
||||||
|
StringError g_rets.GErrorResult[string]
|
||||||
|
|
||||||
|
// Float32Result represents a valid float32 result.
|
||||||
|
Float32Result float32
|
||||||
|
|
||||||
|
// Float32Error represents an invalid float32 result with an error.
|
||||||
|
Float32Error struct{ error }
|
||||||
|
|
||||||
|
// Float64Result represents a valid float64 result.
|
||||||
|
Float64Result float64
|
||||||
|
|
||||||
|
// Float64Error represents an invalid float64 result with an error.
|
||||||
|
Float64Error struct{ error }
|
||||||
|
|
||||||
|
// Complex64Result represents a valid complex64 result.
|
||||||
|
Complex64Result complex64
|
||||||
|
|
||||||
|
// Complex64Error represents an invalid complex64 result with an error.
|
||||||
|
Complex64Error struct{ error }
|
||||||
|
|
||||||
|
// Complex128Result represents a valid complex128 result.
|
||||||
|
Complex128Result complex128
|
||||||
|
|
||||||
|
// Complex128Error represents an invalid complex128 result with an error.
|
||||||
|
Complex128Error struct{ error }
|
||||||
|
)
|
||||||
|
|
||||||
|
// BoolResult *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the BoolResult is valid (always true).
|
||||||
|
func (_ BoolResult) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for BoolResult.
|
||||||
|
func (_ BoolResult) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the integer value for BoolResult.
|
||||||
|
func (r BoolResult) Value() bool { return bool(r) }
|
||||||
|
|
||||||
|
// BoolError *******************************************
|
||||||
|
func NewBoolError(er error) *BoolError {
|
||||||
|
return &BoolError{er}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsValid checks if the BoolError is valid (always false).
|
||||||
|
func (_ BoolError) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for BoolError, as it is considered invalid.
|
||||||
|
func (_ BoolError) Value() bool { return false }
|
||||||
|
|
||||||
|
// Err returns the error for BoolError.
|
||||||
|
func (r BoolError) Err() error { return r.error }
|
||||||
|
|
||||||
|
// StringResult *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the StringResult is valid (always true).
|
||||||
|
func (_ StringResult) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for StringResult.
|
||||||
|
func (_ StringResult) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the integer value for StringResult.
|
||||||
|
func (r StringResult) Value() string { return string(r) }
|
||||||
|
|
||||||
|
// StringError *******************************************
|
||||||
|
func NewStringError(er error) *StringError { return &StringError{er} }
|
||||||
|
|
||||||
|
// IsValid checks if the StringError is valid (always false).
|
||||||
|
func (_ StringError) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for StringError, as it is considered invalid.
|
||||||
|
func (_ StringError) Value() string { return "" }
|
||||||
|
|
||||||
|
// Err returns the error for StringError.
|
||||||
|
func (r StringError) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Float32Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Float32Result is valid (always true).
|
||||||
|
func (_ Float32Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Float32Result.
|
||||||
|
func (_ Float32Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the integer value for Float32Result.
|
||||||
|
func (r Float32Result) Value() float32 { return float32(r) }
|
||||||
|
|
||||||
|
// Float32Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Float32Error is valid (always false).
|
||||||
|
func (_ Float32Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for Float32Error, as it is considered invalid.
|
||||||
|
func (_ Float32Error) Value() float32 { return 0 }
|
||||||
|
|
||||||
|
// Err returns the error for Float32Error.
|
||||||
|
func (r Float32Error) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Float64Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Float64Result is valid (always true).
|
||||||
|
func (_ Float64Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Float64Result.
|
||||||
|
func (_ Float64Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the integer value for Float64Result.
|
||||||
|
func (r Float64Result) Value() float64 { return float64(r) }
|
||||||
|
|
||||||
|
// Float64Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Float64Error is valid (always false).
|
||||||
|
func (_ Float64Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for Float64Error, as it is considered invalid.
|
||||||
|
func (_ Float64Error) Value() float64 { return 0 }
|
||||||
|
|
||||||
|
// Err returns the error for Float64Error.
|
||||||
|
func (r Float64Error) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Complex64Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Complex64Result is valid (always true).
|
||||||
|
func (_ Complex64Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Complex64Result.
|
||||||
|
func (_ Complex64Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the integer value for Complex64Result.
|
||||||
|
func (r Complex64Result) Value() complex64 { return complex64(r) }
|
||||||
|
|
||||||
|
// Complex64Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Complex64Error is valid (always false).
|
||||||
|
func (_ Complex64Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for Complex64Error, as it is considered invalid.
|
||||||
|
func (_ Complex64Error) Value() complex64 { return 0 }
|
||||||
|
|
||||||
|
// Err returns the error for Complex64Error.
|
||||||
|
func (r Complex64Error) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Complex128Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Complex128Result is valid (always true).
|
||||||
|
func (_ Complex128Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Complex128Result.
|
||||||
|
func (_ Complex128Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the integer value for Complex128Result.
|
||||||
|
func (r Complex128Result) Value() complex128 { return complex128(r) }
|
||||||
|
|
||||||
|
// Complex128Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Complex128Error is valid (always false).
|
||||||
|
func (_ Complex128Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for Complex128Error, as it is considered invalid.
|
||||||
|
func (_ Complex128Error) Value() complex128 { return 0 }
|
||||||
|
|
||||||
|
// Err returns the error for Complex128Error.
|
||||||
|
func (r Complex128Error) Err() error { return r.error }
|
||||||
@ -0,0 +1,164 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package rets
|
||||||
|
|
||||||
|
// Type definitions for integer results and errors of different integer types
|
||||||
|
type (
|
||||||
|
|
||||||
|
// IntResult represents a valid integer result.
|
||||||
|
IntResult int
|
||||||
|
// IntError represents an invalid integer result with an error.
|
||||||
|
IntError struct{ error }
|
||||||
|
|
||||||
|
// Int8Result represents a valid int8 result.
|
||||||
|
Int8Result int8
|
||||||
|
// Int8Error represents an invalid int8 result with an error.
|
||||||
|
Int8Error struct{ error }
|
||||||
|
|
||||||
|
// Int16Result represents a valid int16 result.
|
||||||
|
Int16Result int16
|
||||||
|
// Int16Error represents an invalid int16 result with an error.
|
||||||
|
Int16Error struct{ error }
|
||||||
|
|
||||||
|
// Int32Result represents a valid int32 result.
|
||||||
|
Int32Result int32
|
||||||
|
// Int32Error represents an invalid int32 result with an error.
|
||||||
|
Int32Error struct{ error }
|
||||||
|
|
||||||
|
// Int64Result represents a valid int64 result.
|
||||||
|
Int64Result int64
|
||||||
|
// Int64Error represents an invalid int64 result with an error.
|
||||||
|
Int64Error struct{ error }
|
||||||
|
)
|
||||||
|
|
||||||
|
// IntResult *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the IntResult is valid (always true).
|
||||||
|
func (_ IntResult) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for IntResult.
|
||||||
|
func (_ IntResult) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the integer value for IntResult.
|
||||||
|
func (r IntResult) Value() int { return int(r) }
|
||||||
|
|
||||||
|
// IntError *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the IntError is valid (always false, as it represents an error).
|
||||||
|
func (_ IntError) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for IntError, as it is considered invalid.
|
||||||
|
func (_ IntError) Value() int { return 0 }
|
||||||
|
|
||||||
|
// Err returns the error for IntError.
|
||||||
|
func (r IntError) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Int8Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Int8Result is valid (always true).
|
||||||
|
func (_ Int8Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Int8Result.
|
||||||
|
func (_ Int8Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the integer value for Int8Result.
|
||||||
|
func (r Int8Result) Value() int8 { return int8(r) }
|
||||||
|
|
||||||
|
// Int8Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Int8Error is valid (always false).
|
||||||
|
func (_ Int8Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for Int8Error, as it is considered invalid.
|
||||||
|
func (_ Int8Error) Value() int8 { return 0 }
|
||||||
|
|
||||||
|
// Err returns the error for Int8Error.
|
||||||
|
func (r Int8Error) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Int16Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Int16Result is valid (always true).
|
||||||
|
func (_ Int16Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Int16Result.
|
||||||
|
func (_ Int16Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the integer value for Int16Result.
|
||||||
|
func (r Int16Result) Value() int16 { return int16(r) }
|
||||||
|
|
||||||
|
// Int32Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Int32Result is valid (always true).
|
||||||
|
func (_ Int32Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Int32Result.
|
||||||
|
func (_ Int32Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the integer value for Int32Result.
|
||||||
|
func (r Int32Result) Value() int32 { return int32(r) }
|
||||||
|
|
||||||
|
// Int32Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Int32Error is valid (always false).
|
||||||
|
func (_ Int32Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for Int32Error, as it is considered invalid.
|
||||||
|
func (_ Int32Error) Value() int32 { return 0 }
|
||||||
|
|
||||||
|
// Err returns the error for Int32Error.
|
||||||
|
func (r Int32Error) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Int64Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Int64Result is valid (always true).
|
||||||
|
func (_ Int64Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Int64Result.
|
||||||
|
func (_ Int64Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the integer value for Int64Result.
|
||||||
|
func (r Int64Result) Value() int64 { return int64(r) }
|
||||||
|
|
||||||
|
// Int64Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Int64Error is valid (always false).
|
||||||
|
func (_ Int64Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for Int64Error, as it is considered invalid.
|
||||||
|
func (_ Int64Error) Value() int64 { return 0 }
|
||||||
|
|
||||||
|
// Err returns the error for Int64Error.
|
||||||
|
func (r Int64Error) Err() error { return r.error }
|
||||||
@ -0,0 +1,175 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package rets
|
||||||
|
|
||||||
|
// Type definitions for slices of integer results and errors of different integer types
|
||||||
|
type (
|
||||||
|
// IntsResult represents a valid slice of integer results.
|
||||||
|
IntsResult []int
|
||||||
|
// IntsError represents an invalid slice of integer results with an error.
|
||||||
|
IntsError struct{ error }
|
||||||
|
|
||||||
|
// Ints8Result represents a valid slice of int8 results.
|
||||||
|
Ints8Result []int8
|
||||||
|
// Ints8Error represents an invalid slice of int8 results with an error.
|
||||||
|
Ints8Error struct{ error }
|
||||||
|
|
||||||
|
// Ints16Result represents a valid slice of int16 results.
|
||||||
|
Ints16Result []int16
|
||||||
|
// Ints16Error represents an invalid slice of int16 results with an error.
|
||||||
|
Ints16Error struct{ error }
|
||||||
|
|
||||||
|
// Ints32Result represents a valid slice of int32 results.
|
||||||
|
Ints32Result []int32
|
||||||
|
// Ints32Error represents an invalid slice of int32 results with an error.
|
||||||
|
Ints32Error struct{ error }
|
||||||
|
|
||||||
|
// Ints64Result represents a valid slice of int64 results.
|
||||||
|
Ints64Result []int64
|
||||||
|
// Ints64Error represents an invalid slice of int64 results with an error.
|
||||||
|
Ints64Error struct{ error }
|
||||||
|
)
|
||||||
|
|
||||||
|
// IntsResult *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the IntsResult is valid (always true).
|
||||||
|
func (_ IntsResult) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for IntsResult.
|
||||||
|
func (_ IntsResult) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the slice of integers for IntsResult.
|
||||||
|
func (r IntsResult) Value() []int { return r }
|
||||||
|
|
||||||
|
// IntsError *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the IntsError is valid (always false, as it represents an error).
|
||||||
|
func (_ IntsError) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns nil for IntsError, as it is considered invalid.
|
||||||
|
func (_ IntsError) Value() []int { return nil }
|
||||||
|
|
||||||
|
// Err returns the error for IntsError.
|
||||||
|
func (r IntsError) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Ints8Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Ints8Result is valid (always true).
|
||||||
|
func (_ Ints8Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Ints8Result.
|
||||||
|
func (_ Ints8Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the slice of int8 values for Ints8Result.
|
||||||
|
func (r Ints8Result) Value() []int8 { return r }
|
||||||
|
|
||||||
|
// Ints8Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Ints8Error is valid (always false).
|
||||||
|
func (_ Ints8Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns nil for Ints8Error, as it is considered invalid.
|
||||||
|
func (_ Ints8Error) Value() []int8 { return nil }
|
||||||
|
|
||||||
|
// Err returns the error for Ints8Error.
|
||||||
|
func (r Ints8Error) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Ints16Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Ints16Result is valid (always true).
|
||||||
|
func (_ Ints16Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Ints16Result.
|
||||||
|
func (_ Ints16Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the slice of int16 values for Ints16Result.
|
||||||
|
func (r Ints16Result) Value() []int16 { return r }
|
||||||
|
|
||||||
|
// Ints16Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Ints16Error is valid (always false).
|
||||||
|
func (_ Ints16Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns nil for Ints16Error, as it is considered invalid.
|
||||||
|
func (_ Ints16Error) Value() []int16 { return nil }
|
||||||
|
|
||||||
|
// Err returns the error for Ints16Error.
|
||||||
|
func (r Ints16Error) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Ints32Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Ints32Result is valid (always true).
|
||||||
|
func (_ Ints32Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Ints32Result.
|
||||||
|
func (_ Ints32Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the slice of int32 values for Ints32Result.
|
||||||
|
func (r Ints32Result) Value() []int32 { return r }
|
||||||
|
|
||||||
|
// Ints32Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Ints32Error is valid (always false).
|
||||||
|
func (_ Ints32Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns nil for Ints32Error, as it is considered invalid.
|
||||||
|
func (_ Ints32Error) Value() []int32 { return nil }
|
||||||
|
|
||||||
|
// Err returns the error for Ints32Error.
|
||||||
|
func (r Ints32Error) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Ints64Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Ints64Result is valid (always true).
|
||||||
|
func (_ Ints64Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Ints64Result.
|
||||||
|
func (_ Ints64Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the slice of int64 values for Ints64Result.
|
||||||
|
func (r Ints64Result) Value() []int64 { return r }
|
||||||
|
|
||||||
|
// Ints64Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Ints64Error is valid (always false).
|
||||||
|
func (_ Ints64Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns nil for Ints64Error, as it is considered invalid.
|
||||||
|
func (_ Ints64Error) Value() []int64 { return nil }
|
||||||
|
|
||||||
|
// Err returns the error for Ints64Error.
|
||||||
|
func (r Ints64Error) Err() error { return r.error }
|
||||||
@ -0,0 +1,210 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package rets
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
// BoolsResult represents a valid bool result.
|
||||||
|
BoolsResult []bool
|
||||||
|
|
||||||
|
// BoolsError represents an invalid bool result with an error.
|
||||||
|
BoolsError struct{ error }
|
||||||
|
|
||||||
|
// StringsResult represents a valid string result.
|
||||||
|
StringsResult []string
|
||||||
|
|
||||||
|
// StringsError represents an invalid string result with an error.
|
||||||
|
StringsError struct{ error }
|
||||||
|
|
||||||
|
// Floats32Result represents a valid float32 result.
|
||||||
|
Floats32Result []float32
|
||||||
|
|
||||||
|
// Floats32Error represents an invalid float32 result with an error.
|
||||||
|
Floats32Error struct{ error }
|
||||||
|
|
||||||
|
// Floats64Result represents a valid float64 result.
|
||||||
|
Floats64Result []float64
|
||||||
|
|
||||||
|
// Floats64Error represents an invalid float64 result with an error.
|
||||||
|
Floats64Error struct{ error }
|
||||||
|
|
||||||
|
// Complexs64Result represents a valid complex64 result.
|
||||||
|
Complexs64Result []complex64
|
||||||
|
|
||||||
|
// Complexs64Error represents an invalid complex64 result with an error.
|
||||||
|
Complexs64Error struct{ error }
|
||||||
|
|
||||||
|
// Complexs128Result represents a valid complex128 result.
|
||||||
|
Complexs128Result []complex128
|
||||||
|
|
||||||
|
// Complexs128Error represents an invalid complex128 result with an error.
|
||||||
|
Complexs128Error struct{ error }
|
||||||
|
)
|
||||||
|
|
||||||
|
// BoolResult *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the BoolResult is valid (always true).
|
||||||
|
func (_ BoolsResult) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for BoolResult.
|
||||||
|
func (_ BoolsResult) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the integer value for BoolResult.
|
||||||
|
func (r BoolsResult) Value() []bool { return r }
|
||||||
|
|
||||||
|
// BoolError *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the BoolError is valid (always false).
|
||||||
|
func (_ BoolsError) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for BoolError, as it is considered invalid.
|
||||||
|
func (_ BoolsError) Value() []bool { return nil }
|
||||||
|
|
||||||
|
// Err returns the error for BoolError.
|
||||||
|
func (r BoolsError) Err() error { return r.error }
|
||||||
|
|
||||||
|
// StringResult *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the StringResult is valid (always true).
|
||||||
|
func (_ StringsResult) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for StringResult.
|
||||||
|
func (_ StringsResult) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the integer value for StringResult.
|
||||||
|
func (r StringsResult) Value() []string { return r }
|
||||||
|
|
||||||
|
// StringError *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the StringError is valid (always false).
|
||||||
|
func (_ StringsError) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for StringError, as it is considered invalid.
|
||||||
|
func (_ StringsError) Value() []string { return nil }
|
||||||
|
|
||||||
|
// Err returns the error for StringError.
|
||||||
|
func (r StringsError) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Float32Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Float32Result is valid (always true).
|
||||||
|
func (_ Floats32Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Float32Result.
|
||||||
|
func (_ Floats32Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the integer value for Float32Result.
|
||||||
|
func (r Floats32Result) Value() []float32 { return r }
|
||||||
|
|
||||||
|
// Float32Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Float32Error is valid (always false).
|
||||||
|
func (_ Floats32Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for Float32Error, as it is considered invalid.
|
||||||
|
func (_ Floats32Error) Value() []float32 { return nil }
|
||||||
|
|
||||||
|
// Err returns the error for Float32Error.
|
||||||
|
func (r Floats32Error) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Float64Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Float64Result is valid (always true).
|
||||||
|
func (_ Floats64Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Float64Result.
|
||||||
|
func (_ Floats64Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the integer value for Float64Result.
|
||||||
|
func (r Floats64Result) Value() []float64 { return r }
|
||||||
|
|
||||||
|
// Float64Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Float64Error is valid (always false).
|
||||||
|
func (_ Floats64Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for Float64Error, as it is considered invalid.
|
||||||
|
func (_ Floats64Error) Value() []float64 { return nil }
|
||||||
|
|
||||||
|
// Err returns the error for Float64Error.
|
||||||
|
func (r Floats64Error) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Complex64Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Complex64Result is valid (always true).
|
||||||
|
func (_ Complexs64Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Complex64Result.
|
||||||
|
func (_ Complexs64Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the integer value for Complex64Result.
|
||||||
|
func (r Complexs64Result) Value() []complex64 { return r }
|
||||||
|
|
||||||
|
// Complex64Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Complex64Error is valid (always false).
|
||||||
|
func (_ Complexs64Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for Complex64Error, as it is considered invalid.
|
||||||
|
func (_ Complexs64Error) Value() []complex64 { return nil }
|
||||||
|
|
||||||
|
// Err returns the error for Complex64Error.
|
||||||
|
func (r Complexs64Error) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Complex128Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Complex128Result is valid (always true).
|
||||||
|
func (_ Complexs128Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Complex128Result.
|
||||||
|
func (_ Complexs128Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the integer value for Complex128Result.
|
||||||
|
func (r Complexs128Result) Value() []complex128 { return r }
|
||||||
|
|
||||||
|
// Complex128Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Complex128Error is valid (always false).
|
||||||
|
func (_ Complexs128Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for Complex128Error, as it is considered invalid.
|
||||||
|
func (_ Complexs128Error) Value() []complex128 { return nil }
|
||||||
|
|
||||||
|
// Err returns the error for Complex128Error.
|
||||||
|
func (r Complexs128Error) Err() error { return r.error }
|
||||||
@ -0,0 +1,181 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package rets
|
||||||
|
|
||||||
|
// Type definitions for unsigned results and errors of different unsigned types
|
||||||
|
type (
|
||||||
|
|
||||||
|
// UintResult represents a valid unsigned result.
|
||||||
|
UintResult uint
|
||||||
|
|
||||||
|
// UintError represents an invalid unsigned result with an error.
|
||||||
|
UintError struct{ error }
|
||||||
|
|
||||||
|
// Uint8Result represents a valid uint8 result.
|
||||||
|
Uint8Result uint8
|
||||||
|
|
||||||
|
// Uint8Error represents an invalid uint8 result with an error.
|
||||||
|
Uint8Error struct{ error }
|
||||||
|
|
||||||
|
// Uint16Result represents a valid uint16 result.
|
||||||
|
Uint16Result uint16
|
||||||
|
|
||||||
|
// Uint16Error represents an invalid uint16 result with an error.
|
||||||
|
Uint16Error struct{ error }
|
||||||
|
|
||||||
|
// Uint32Result represents a valid uint32 result.
|
||||||
|
Uint32Result uint32
|
||||||
|
|
||||||
|
// Uint32Error represents an invalid uint32 result with an error.
|
||||||
|
Uint32Error struct{ error }
|
||||||
|
|
||||||
|
// Uint64Result represents a valid uint64 result.
|
||||||
|
Uint64Result uint64
|
||||||
|
|
||||||
|
// Uint64Error represents an invalid uint64 result with an error.
|
||||||
|
Uint64Error struct{ error }
|
||||||
|
)
|
||||||
|
|
||||||
|
// UintResult *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the UintResult is valid (always true).
|
||||||
|
func (_ UintResult) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for UintResult.
|
||||||
|
func (_ UintResult) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the uinteger value for UintResult.
|
||||||
|
func (r UintResult) Value() uint { return uint(r) }
|
||||||
|
|
||||||
|
// UintError *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the UintError is valid (always false, as it represents an error).
|
||||||
|
func (_ UintError) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for UintError, as it is considered invalid.
|
||||||
|
func (_ UintError) Value() uint { return 0 }
|
||||||
|
|
||||||
|
// Err returns the error for UintError.
|
||||||
|
func (r UintError) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Uint8Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Uint8Result is valid (always true).
|
||||||
|
func (_ Uint8Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Uint8Result.
|
||||||
|
func (_ Uint8Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the uinteger value for Uint8Result.
|
||||||
|
func (r Uint8Result) Value() uint8 { return uint8(r) }
|
||||||
|
|
||||||
|
// Uint8Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Uint8Error is valid (always false).
|
||||||
|
func (_ Uint8Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for Uint8Error, as it is considered invalid.
|
||||||
|
func (_ Uint8Error) Value() uint8 { return 0 }
|
||||||
|
|
||||||
|
// Err returns the error for Uint8Error.
|
||||||
|
func (r Uint8Error) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Uint16Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Uint16Result is valid (always true).
|
||||||
|
func (_ Uint16Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Uint16Result.
|
||||||
|
func (_ Uint16Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the uinteger value for Uint16Result.
|
||||||
|
func (r Uint16Result) Value() uint16 { return uint16(r) }
|
||||||
|
|
||||||
|
// Uint16Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Uint16Error is valid (always false).
|
||||||
|
func (_ Uint16Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for Uint16Error, as it is considered invalid.
|
||||||
|
func (_ Uint16Error) Value() uint16 { return 0 }
|
||||||
|
|
||||||
|
// Err returns the error for Uint16Error.
|
||||||
|
func (r Uint16Error) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Uint32Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Uint32Result is valid (always true).
|
||||||
|
func (_ Uint32Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Uint32Result.
|
||||||
|
func (_ Uint32Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the uinteger value for Uint32Result.
|
||||||
|
func (r Uint32Result) Value() uint32 { return uint32(r) }
|
||||||
|
|
||||||
|
// Uint32Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Uint32Error is valid (always false).
|
||||||
|
func (_ Uint32Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for Uint32Error, as it is considered invalid.
|
||||||
|
func (_ Uint32Error) Value() uint32 { return 0 }
|
||||||
|
|
||||||
|
// Err returns the error for Uint32Error.
|
||||||
|
func (r Uint32Error) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Uint64Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Uint64Result is valid (always true).
|
||||||
|
func (_ Uint64Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Uint64Result.
|
||||||
|
func (_ Uint64Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the uinteger value for Uint64Result.
|
||||||
|
func (r Uint64Result) Value() uint64 { return uint64(r) }
|
||||||
|
|
||||||
|
// Uint64Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Uint64Error is valid (always false).
|
||||||
|
func (_ Uint64Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns 0 for Uint64Error, as it is considered invalid.
|
||||||
|
func (_ Uint64Error) Value() uint64 { return 0 }
|
||||||
|
|
||||||
|
// Err returns the error for Uint64Error.
|
||||||
|
func (r Uint64Error) Err() error { return r.error }
|
||||||
@ -0,0 +1,181 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package rets
|
||||||
|
|
||||||
|
// Type definitions for slices of unsigned results and errors of different unsigned types
|
||||||
|
type (
|
||||||
|
|
||||||
|
// UintsResult represents a valid slice of unsigned results.
|
||||||
|
UintsResult []uint
|
||||||
|
|
||||||
|
// UintsError represents an invalid slice of unsigned results with an error.
|
||||||
|
UintsError struct{ error }
|
||||||
|
|
||||||
|
// Uints8Result represents a valid slice of uint8 results.
|
||||||
|
Uints8Result []uint8
|
||||||
|
|
||||||
|
// Uints8Error represents an invalid slice of uint8 results with an error.
|
||||||
|
Uints8Error struct{ error }
|
||||||
|
|
||||||
|
// Uints16Result represents a valid slice of uint16 results.
|
||||||
|
Uints16Result []uint16
|
||||||
|
|
||||||
|
// Uints16Error represents an invalid slice of uint16 results with an error.
|
||||||
|
Uints16Error struct{ error }
|
||||||
|
|
||||||
|
// Uints32Result represents a valid slice of uint32 results.
|
||||||
|
Uints32Result []uint32
|
||||||
|
|
||||||
|
// Uints32Error represents an invalid slice of uint32 results with an error.
|
||||||
|
Uints32Error struct{ error }
|
||||||
|
|
||||||
|
// Uints64Result represents a valid slice of uint64 results.
|
||||||
|
Uints64Result []uint64
|
||||||
|
|
||||||
|
// Uints64Error represents an invalid slice of uint64 results with an error.
|
||||||
|
Uints64Error struct{ error }
|
||||||
|
)
|
||||||
|
|
||||||
|
// UintsResult *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the UintsResult is valid (always true).
|
||||||
|
func (_ UintsResult) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for UintsResult.
|
||||||
|
func (_ UintsResult) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the slice of unsigned for UintsResult.
|
||||||
|
func (r UintsResult) Value() []uint { return r }
|
||||||
|
|
||||||
|
// UintsError *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the UintsError is valid (always false, as it represents an error).
|
||||||
|
func (_ UintsError) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns nil for UintsError, as it is considered invalid.
|
||||||
|
func (_ UintsError) Value() []uint { return nil }
|
||||||
|
|
||||||
|
// Err returns the error for UintsError.
|
||||||
|
func (r UintsError) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Uints8Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Uints8Result is valid (always true).
|
||||||
|
func (_ Uints8Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Uints8Result.
|
||||||
|
func (_ Uints8Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the slice of uint8 values for Uints8Result.
|
||||||
|
func (r Uints8Result) Value() []uint8 { return r }
|
||||||
|
|
||||||
|
// Uints8Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Uints8Error is valid (always false).
|
||||||
|
func (_ Uints8Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns nil for Uints8Error, as it is considered invalid.
|
||||||
|
func (_ Uints8Error) Value() []uint8 { return nil }
|
||||||
|
|
||||||
|
// Err returns the error for Uints8Error.
|
||||||
|
func (r Uints8Error) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Uints16Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Uints16Result is valid (always true).
|
||||||
|
func (_ Uints16Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Uints16Result.
|
||||||
|
func (_ Uints16Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the slice of uint16 values for Uints16Result.
|
||||||
|
func (r Uints16Result) Value() []uint16 { return r }
|
||||||
|
|
||||||
|
// Uints16Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Uints16Error is valid (always false).
|
||||||
|
func (_ Uints16Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns nil for Uints16Error, as it is considered invalid.
|
||||||
|
func (_ Uints16Error) Value() []uint16 { return nil }
|
||||||
|
|
||||||
|
// Err returns the error for Uints16Error.
|
||||||
|
func (r Uints16Error) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Uints32Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Uints32Result is valid (always true).
|
||||||
|
func (_ Uints32Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Uints32Result.
|
||||||
|
func (_ Uints32Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the slice of uint32 values for Uints32Result.
|
||||||
|
func (r Uints32Result) Value() []uint32 { return r }
|
||||||
|
|
||||||
|
// Uints32Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Uints32Error is valid (always false).
|
||||||
|
func (_ Uints32Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns nil for Uints32Error, as it is considered invalid.
|
||||||
|
func (_ Uints32Error) Value() []uint32 { return nil }
|
||||||
|
|
||||||
|
// Err returns the error for Uints32Error.
|
||||||
|
func (r Uints32Error) Err() error { return r.error }
|
||||||
|
|
||||||
|
// Uints64Result *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Uints64Result is valid (always true).
|
||||||
|
func (_ Uints64Result) IsValid() bool { return true }
|
||||||
|
|
||||||
|
// Err returns nil as there is no error for Uints64Result.
|
||||||
|
func (_ Uints64Result) Err() error { return nil }
|
||||||
|
|
||||||
|
// Value returns the slice of uint64 values for Uints64Result.
|
||||||
|
func (r Uints64Result) Value() []uint64 { return r }
|
||||||
|
|
||||||
|
// Uints64Error *******************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
// IsValid checks if the Uints64Error is valid (always false).
|
||||||
|
func (_ Uints64Error) IsValid() bool { return false }
|
||||||
|
|
||||||
|
// Value returns nil for Uints64Error, as it is considered invalid.
|
||||||
|
func (_ Uints64Error) Value() []uint64 { return nil }
|
||||||
|
|
||||||
|
// Err returns the error for Uints64Error.
|
||||||
|
func (r Uints64Error) Err() error { return r.error }
|
||||||
@ -0,0 +1,216 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package rets
|
||||||
|
|
||||||
|
import "core/rets/g_rets"
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
// String
|
||||||
|
StringResultor = g_rets.GResultor[string]
|
||||||
|
StringValidator = g_rets.GValidator[string]
|
||||||
|
ValidString string
|
||||||
|
InvalidString struct{}
|
||||||
|
|
||||||
|
// Bool
|
||||||
|
BoolResultor = g_rets.GResultor[bool]
|
||||||
|
BoolValidator = g_rets.GValidator[bool]
|
||||||
|
ValidBool bool
|
||||||
|
InvalidBool struct{}
|
||||||
|
|
||||||
|
// Ints
|
||||||
|
IntValidator = g_rets.GValidator[int]
|
||||||
|
ValidInt int
|
||||||
|
InvalidInt struct{}
|
||||||
|
|
||||||
|
Int8Validator = g_rets.GValidator[int8]
|
||||||
|
ValidInt8 int8
|
||||||
|
InvalidInt8 struct{}
|
||||||
|
|
||||||
|
Int16Validator = g_rets.GValidator[int16]
|
||||||
|
ValidInt16 int16
|
||||||
|
InvalidInt16 struct{}
|
||||||
|
|
||||||
|
Int32Validator = g_rets.GValidator[int32]
|
||||||
|
ValidInt32 int32
|
||||||
|
InvalidInt32 struct{}
|
||||||
|
|
||||||
|
Int64Validator = g_rets.GValidator[int64]
|
||||||
|
ValidInt64 int64
|
||||||
|
InvalidInt64 struct{}
|
||||||
|
|
||||||
|
// Uints
|
||||||
|
UintValidator = g_rets.GValidator[uint]
|
||||||
|
ValidUint uint
|
||||||
|
InvalidUint struct{}
|
||||||
|
|
||||||
|
Uint8Validator = g_rets.GValidator[uint8]
|
||||||
|
ValidUint8 uint8
|
||||||
|
InvalidUint8 struct{}
|
||||||
|
|
||||||
|
Uint16Validator = g_rets.GValidator[uint16]
|
||||||
|
ValidUint16 uint16
|
||||||
|
InvalidUint16 struct{}
|
||||||
|
|
||||||
|
Uint32Validator = g_rets.GValidator[uint32]
|
||||||
|
ValidUint32 uint32
|
||||||
|
InvalidUint32 struct{}
|
||||||
|
|
||||||
|
Uint64Validator = g_rets.GValidator[uint64]
|
||||||
|
ValidUint64 uint64
|
||||||
|
InvalidUint64 struct{}
|
||||||
|
|
||||||
|
// Floats
|
||||||
|
Float32Validator = g_rets.GValidator[float32]
|
||||||
|
ValidFloat32 float32
|
||||||
|
InvalidFloat32 struct{}
|
||||||
|
|
||||||
|
FloatValidator = g_rets.GValidator[float64]
|
||||||
|
ValidFloat64 float64
|
||||||
|
InvalidFloat64 struct{}
|
||||||
|
|
||||||
|
// Complex
|
||||||
|
Complex64Validator = g_rets.GValidator[complex64]
|
||||||
|
ValidComplex64 complex64
|
||||||
|
InvalidComplex64 struct{}
|
||||||
|
|
||||||
|
Complex128Validator = g_rets.GValidator[complex128]
|
||||||
|
ValidComplex128 complex128
|
||||||
|
InvalidComplex128 struct{}
|
||||||
|
)
|
||||||
|
|
||||||
|
// String Methods
|
||||||
|
func (_ ValidString) IsValid() bool { return true }
|
||||||
|
func (r ValidString) Value() string { return string(r) }
|
||||||
|
|
||||||
|
func (_ InvalidString) IsValid() bool { return false }
|
||||||
|
func (_ InvalidString) Value() string { return "" }
|
||||||
|
|
||||||
|
// Bool Methods
|
||||||
|
func (_ ValidBool) IsValid() bool { return true }
|
||||||
|
func (r ValidBool) Value() bool { return bool(r) }
|
||||||
|
|
||||||
|
func (_ InvalidBool) IsValid() bool { return false }
|
||||||
|
func (_ InvalidBool) Value() bool { return false }
|
||||||
|
|
||||||
|
// Int Methods
|
||||||
|
func (_ ValidInt) IsValid() bool { return true }
|
||||||
|
func (r ValidInt) Value() int { return int(r) }
|
||||||
|
|
||||||
|
func (_ InvalidInt) IsValid() bool { return false }
|
||||||
|
func (_ InvalidInt) Value() int { return 0 }
|
||||||
|
|
||||||
|
// Int8 Methods
|
||||||
|
func (_ ValidInt8) IsValid() bool { return true }
|
||||||
|
func (r ValidInt8) Value() int8 { return int8(r) }
|
||||||
|
|
||||||
|
func (_ InvalidInt8) IsValid() bool { return false }
|
||||||
|
func (_ InvalidInt8) Value() int8 { return 0 }
|
||||||
|
|
||||||
|
// Int16 Methods
|
||||||
|
func (_ ValidInt16) IsValid() bool { return true }
|
||||||
|
func (r ValidInt16) Value() int16 { return int16(r) }
|
||||||
|
|
||||||
|
func (_ InvalidInt16) IsValid() bool { return false }
|
||||||
|
func (_ InvalidInt16) Value() int16 { return 0 }
|
||||||
|
|
||||||
|
// Int32 Methods
|
||||||
|
func (_ ValidInt32) IsValid() bool { return true }
|
||||||
|
func (r ValidInt32) Value() int32 { return int32(r) }
|
||||||
|
|
||||||
|
func (_ InvalidInt32) IsValid() bool { return false }
|
||||||
|
func (_ InvalidInt32) Value() int32 { return 0 }
|
||||||
|
|
||||||
|
// Int64 Methods
|
||||||
|
func (_ ValidInt64) IsValid() bool { return true }
|
||||||
|
func (r ValidInt64) Value() int64 { return int64(r) }
|
||||||
|
|
||||||
|
func (_ InvalidInt64) IsValid() bool { return false }
|
||||||
|
func (_ InvalidInt64) Value() int64 { return 0 }
|
||||||
|
|
||||||
|
// Uint Methods
|
||||||
|
func (_ ValidUint) IsValid() bool { return true }
|
||||||
|
func (r ValidUint) Value() uint { return uint(r) }
|
||||||
|
|
||||||
|
func (_ InvalidUint) IsValid() bool { return false }
|
||||||
|
func (_ InvalidUint) Value() uint { return 0 }
|
||||||
|
|
||||||
|
// Uint8 Methods
|
||||||
|
func (_ ValidUint8) IsValid() bool { return true }
|
||||||
|
func (r ValidUint8) Value() uint8 { return uint8(r) }
|
||||||
|
|
||||||
|
func (_ InvalidUint8) IsValid() bool { return false }
|
||||||
|
func (_ InvalidUint8) Value() uint8 { return 0 }
|
||||||
|
|
||||||
|
// Uint16 Methods
|
||||||
|
func (_ ValidUint16) IsValid() bool { return true }
|
||||||
|
func (r ValidUint16) Value() uint16 { return uint16(r) }
|
||||||
|
|
||||||
|
func (_ InvalidUint16) IsValid() bool { return false }
|
||||||
|
func (_ InvalidUint16) Value() uint16 { return 0 }
|
||||||
|
|
||||||
|
// Uint32 Methods
|
||||||
|
func (_ ValidUint32) IsValid() bool { return true }
|
||||||
|
func (r ValidUint32) Value() uint32 { return uint32(r) }
|
||||||
|
|
||||||
|
func (_ InvalidUint32) IsValid() bool { return false }
|
||||||
|
func (_ InvalidUint32) Value() uint32 { return 0 }
|
||||||
|
|
||||||
|
// Uint64 Methods
|
||||||
|
func (_ ValidUint64) IsValid() bool { return true }
|
||||||
|
func (r ValidUint64) Value() uint64 { return uint64(r) }
|
||||||
|
|
||||||
|
func (_ InvalidUint64) IsValid() bool { return false }
|
||||||
|
func (_ InvalidUint64) Value() uint64 { return 0 }
|
||||||
|
|
||||||
|
// Float32 Methods
|
||||||
|
func (_ ValidFloat32) IsValid() bool { return true }
|
||||||
|
func (r ValidFloat32) Value() float32 { return float32(r) }
|
||||||
|
|
||||||
|
func (_ InvalidFloat32) IsValid() bool { return false }
|
||||||
|
func (_ InvalidFloat32) Value() float32 { return 0 }
|
||||||
|
|
||||||
|
// Float64 Methods
|
||||||
|
func (_ ValidFloat64) IsValid() bool { return true }
|
||||||
|
func (r ValidFloat64) Value() float64 { return float64(r) }
|
||||||
|
|
||||||
|
func (_ InvalidFloat64) IsValid() bool { return false }
|
||||||
|
func (_ InvalidFloat64) Value() float64 { return 0 }
|
||||||
|
|
||||||
|
// Complex64 Methods
|
||||||
|
func (_ ValidComplex64) IsValid() bool { return true }
|
||||||
|
func (r ValidComplex64) Value() complex64 { return complex64(r) }
|
||||||
|
|
||||||
|
func (_ InvalidComplex64) IsValid() bool { return false }
|
||||||
|
func (_ InvalidComplex64) Value() complex64 { return 0 }
|
||||||
|
|
||||||
|
// Complex128 Methods
|
||||||
|
func (_ ValidComplex128) IsValid() bool { return true }
|
||||||
|
func (r ValidComplex128) Value() complex128 { return complex128(r) }
|
||||||
|
|
||||||
|
func (_ InvalidComplex128) IsValid() bool { return false }
|
||||||
|
func (_ InvalidComplex128) Value() complex128 { return 0 }
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package rets
|
||||||
|
|
||||||
|
import "core/rets/g_rets"
|
||||||
|
|
||||||
|
// ValueResult is an alias for the GValueResult type from the g_rets package.
|
||||||
|
// This alias simplifies usage by referring to GValueResult with the generic type `any`,
|
||||||
|
// making it easier to work with any type of value as a result in the program.
|
||||||
|
type ValueResult = g_rets.GValueResult[any]
|
||||||
|
|
||||||
|
// NewValueResult creates a new instance of ValueResult using the g_rets package's NewGValueResult function.
|
||||||
|
// It takes a value of any type as input and returns a pointer to a ValueResult containing that value.
|
||||||
|
//
|
||||||
|
// The function uses the `any` type for generic handling, allowing you to create value results
|
||||||
|
// for any specific type of value that needs to be encapsulated in the result.
|
||||||
|
func NewValueResult(value any) *ValueResult {
|
||||||
|
// Create and return a value result using the provided value.
|
||||||
|
return g_rets.NewGValueResult[any](value)
|
||||||
|
}
|
||||||
@ -0,0 +1,65 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package blds
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Builder interface {
|
||||||
|
Any(value any)
|
||||||
|
|
||||||
|
Raw(value []byte)
|
||||||
|
|
||||||
|
Binary(value []byte)
|
||||||
|
String(value string)
|
||||||
|
|
||||||
|
Bool(value bool)
|
||||||
|
|
||||||
|
Int(value int)
|
||||||
|
Int8(value int8)
|
||||||
|
Int16(value int16)
|
||||||
|
Int32(value int32)
|
||||||
|
Int64(value int64)
|
||||||
|
|
||||||
|
Uint(value uint)
|
||||||
|
Uint8(value uint8)
|
||||||
|
Uint16(value uint16)
|
||||||
|
Uint32(value uint32)
|
||||||
|
Uint64(value uint64)
|
||||||
|
Uintptr(value uintptr)
|
||||||
|
|
||||||
|
Float32(value float32)
|
||||||
|
Float64(value float64)
|
||||||
|
|
||||||
|
Error(value error)
|
||||||
|
|
||||||
|
Time(value time.Time)
|
||||||
|
Duration(value time.Duration)
|
||||||
|
|
||||||
|
List(buildFn func(b ListBuilder))
|
||||||
|
Map(buildFn func(b MapBuilder))
|
||||||
|
Object(buildFn func(b ObjectBuilder))
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package blds
|
||||||
|
|
||||||
|
type (
|
||||||
|
FieldsBuilder interface {
|
||||||
|
Build(builder ObjectBuilder)
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldsBuilderFnc func(builder ObjectBuilder)
|
||||||
|
)
|
||||||
|
|
||||||
|
func (f FieldsBuilderFnc) BuildField(builder ObjectBuilder) {
|
||||||
|
f(builder)
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package blds
|
||||||
|
|
||||||
|
type (
|
||||||
|
ListBuilder interface {
|
||||||
|
BuildItem() Builder
|
||||||
|
}
|
||||||
|
|
||||||
|
ListBuilderFnc func() Builder
|
||||||
|
)
|
||||||
|
|
||||||
|
func (f ListBuilderFnc) BuildItem() Builder {
|
||||||
|
return f()
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package blds
|
||||||
|
|
||||||
|
type (
|
||||||
|
MapBuilder interface {
|
||||||
|
BuildElement(key any) Builder
|
||||||
|
}
|
||||||
|
|
||||||
|
MapBuilderFnc func(key any) Builder
|
||||||
|
)
|
||||||
|
|
||||||
|
func (f MapBuilderFnc) BuildElement(key any) Builder {
|
||||||
|
return f(key)
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package blds
|
||||||
|
|
||||||
|
type (
|
||||||
|
ObjectBuilder interface {
|
||||||
|
BuildField(name string) Builder
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectBuilderFnc func(name string) Builder
|
||||||
|
)
|
||||||
|
|
||||||
|
func (f ObjectBuilderFnc) BuildField(name string) Builder {
|
||||||
|
return f(name)
|
||||||
|
}
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package flds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"core/errs"
|
||||||
|
"core/rets"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// namePattern is the regular expression that defines a valid error code format.
|
||||||
|
// The error code can optionally have a module, which is separated by "::".
|
||||||
|
// The valid characters are alphanumeric characters and the symbols ":-_".
|
||||||
|
namePattern string = "^[a-zA-Z][a-zA-Z0-9_-]*$"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
moduleName = "core.vals.flds" + errs.ModuleSeparator
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
G = struct {
|
||||||
|
ErrInvalidName,
|
||||||
|
ErrInvalidValue,
|
||||||
|
ErrInvalidCast,
|
||||||
|
ErrDuplicatedName errs.ErrCode
|
||||||
|
}{
|
||||||
|
|
||||||
|
ErrInvalidCast: errs.MakeErrCode(moduleName + "invalid-cast-type"),
|
||||||
|
ErrInvalidName: errs.MakeErrCode(moduleName + "invalid-field-name"),
|
||||||
|
}
|
||||||
|
|
||||||
|
g = struct {
|
||||||
|
nameValidator *regexp.Regexp
|
||||||
|
boolCastError rets.BoolError
|
||||||
|
stringCastError rets.StringError
|
||||||
|
}{
|
||||||
|
|
||||||
|
nameValidator: regexp.MustCompile(namePattern),
|
||||||
|
|
||||||
|
boolCastError: *rets.NewBoolError(G.ErrInvalidCast),
|
||||||
|
stringCastError: *rets.NewStringError(G.ErrInvalidCast),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func ValidateName(name string) bool {
|
||||||
|
return g.nameValidator.MatchString(name)
|
||||||
|
}
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package flds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"core/rets"
|
||||||
|
"core/vals"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Field struct {
|
||||||
|
vals.ValueProvider
|
||||||
|
name string
|
||||||
|
kind Kind
|
||||||
|
}
|
||||||
|
|
||||||
|
func newField(provider vals.ValueProvider, name string, kind Kind) *Field {
|
||||||
|
return &Field{
|
||||||
|
ValueProvider: provider,
|
||||||
|
name: name,
|
||||||
|
kind: kind,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f Field) Name() string {
|
||||||
|
return f.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f Field) Kind() Kind {
|
||||||
|
return f.kind
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f Field) AsString() rets.StringResultor {
|
||||||
|
if f.kind.IsString() {
|
||||||
|
return rets.StringResult((f.Value()).(string))
|
||||||
|
}
|
||||||
|
if vl, is := (f.Value()).(string); is {
|
||||||
|
return rets.StringResult(vl)
|
||||||
|
}
|
||||||
|
return g.stringCastError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f Field) AsBool() rets.BoolResultor {
|
||||||
|
if f.kind.IsBool() {
|
||||||
|
return rets.BoolResult((f.Value()).(bool))
|
||||||
|
}
|
||||||
|
if vl, is := (f.Value()).(bool); is {
|
||||||
|
return rets.BoolResult(vl)
|
||||||
|
}
|
||||||
|
return g.boolCastError
|
||||||
|
}
|
||||||
@ -0,0 +1,98 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package flds
|
||||||
|
|
||||||
|
const (
|
||||||
|
KindAny Kind = 1 << iota
|
||||||
|
KindBool
|
||||||
|
KindBinary
|
||||||
|
KindString
|
||||||
|
KindInt
|
||||||
|
KindUint
|
||||||
|
KindFloat
|
||||||
|
KindTime
|
||||||
|
KindDuration
|
||||||
|
KindError
|
||||||
|
KindReflect
|
||||||
|
|
||||||
|
KindDefer Kind = 8192
|
||||||
|
KindDeferOnce Kind = 16384
|
||||||
|
|
||||||
|
typesMask Kind = 0b0000011111111111
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
Kind uint16
|
||||||
|
)
|
||||||
|
|
||||||
|
func (k Kind) DataType() Kind {
|
||||||
|
return k & typesMask
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kind) IsAny() bool {
|
||||||
|
return k&KindAny != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kind) IsBool() bool {
|
||||||
|
return k&KindBool != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kind) IsInt() bool {
|
||||||
|
return k&KindInt != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kind) IsUint() bool {
|
||||||
|
return k&KindUint != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kind) IsFloat() bool {
|
||||||
|
return k&KindFloat != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kind) IsString() bool {
|
||||||
|
return k&KindString != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kind) IsTime() bool {
|
||||||
|
return k&KindTime != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kind) IsDuration() bool {
|
||||||
|
return k&KindDuration != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kind) IsBinary() bool {
|
||||||
|
return k&KindBinary != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kind) IsError() bool {
|
||||||
|
return k&KindError != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kind) IsReflect() bool {
|
||||||
|
return k&KindReflect != 0
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package g_vals
|
||||||
|
|
||||||
|
import "core/rets/g_rets"
|
||||||
|
|
||||||
|
type (
|
||||||
|
// GKeyValueGetter defines a generic interface for retrieving values from a key-value store.
|
||||||
|
// The interface is parameterized with two type parameters:
|
||||||
|
// K: The key type, which must be comparable
|
||||||
|
// T: The value type, which can be any type
|
||||||
|
//
|
||||||
|
// This interface provides a single method for value retrieval that returns
|
||||||
|
// a generic result type, allowing for type-safe error handling.
|
||||||
|
GKeyValueGetter[K comparable, T any] interface {
|
||||||
|
// GetValue retrieves a value of type T associated with the given key.
|
||||||
|
// Returns a GResulter containing either the value or an error.
|
||||||
|
GetValue(key K) g_rets.GResultor[T]
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetKeyValueFnc is a function type that implements the GKeyValueGetter interface.
|
||||||
|
// It allows simple functions to be used as key-value getters without creating
|
||||||
|
// a full struct implementation.
|
||||||
|
//
|
||||||
|
// Type parameters:
|
||||||
|
// K: The key type, which must be comparable
|
||||||
|
// T: The value type, which can be any type
|
||||||
|
//
|
||||||
|
// This type enables functional programming patterns and easy adaptation
|
||||||
|
// of existing functions to the GKeyValueGetter interface.
|
||||||
|
GetKeyValueFnc[K comparable, T any] func(key K) g_rets.GResultor[T]
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetValue implements the GKeyValueGetter interface for the GetKeyValueFnc type.
|
||||||
|
// This method allows the function type to be used directly as a GKeyValueGetter.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - key: The key of type K to look up
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - g_rets.GResulter[T]: The result of calling the underlying function
|
||||||
|
func (f GetKeyValueFnc[K, T]) GetValue(key K) g_rets.GResultor[T] {
|
||||||
|
return f(key)
|
||||||
|
}
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package g_vals
|
||||||
|
|
||||||
|
type (
|
||||||
|
// GNameValueSetter defines a generic interface for storing values in a name-value store.
|
||||||
|
// The interface is parameterized with type parameter:
|
||||||
|
// T: The value type, which can be any type
|
||||||
|
//
|
||||||
|
// This interface provides a single method for storing values with type safety
|
||||||
|
// and error handling.
|
||||||
|
GNameValueSetter[T any] interface {
|
||||||
|
// SetValue stores a value of type T associated with the given name.
|
||||||
|
// Returns an error if the operation fails.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - name: The string name under which to store the value
|
||||||
|
// - value: The value to store
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - error: nil if successful, otherwise an error describing the failure
|
||||||
|
SetValue(name string, value T) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// GNameValueSetterFnc is a function type that implements the GNameValueSetter interface.
|
||||||
|
// It allows simple functions to be used as name-value setters without creating
|
||||||
|
// a full struct implementation.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - name: The string name under which to store the value
|
||||||
|
// Type parameters:
|
||||||
|
// T: The value type, which can be any type
|
||||||
|
//
|
||||||
|
// This type enables functional programming patterns and easy adaptation
|
||||||
|
// of existing functions to the GNameValueSetter interface.
|
||||||
|
GNameValueSetterFnc[T any] func(name string, value T) error
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetValue implements the GNameValueSetter interface for the GKeyValueSetterFnc type.
|
||||||
|
// This method allows the function type to be used directly as a GNameValueSetter.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - name: The name string under which to store the value
|
||||||
|
// - value: The value of type T to store
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - error: The result of calling the underlying function
|
||||||
|
func (f GNameValueSetterFnc[T]) SetValue(name string, value T) error {
|
||||||
|
return f(name, value)
|
||||||
|
}
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package g_vals
|
||||||
|
|
||||||
|
// GNameValueGetter is a generic interface that defines a contract for retrieving
|
||||||
|
// values of type T using a string name as the key.
|
||||||
|
//
|
||||||
|
// Type Parameters:
|
||||||
|
// - T: The type of value to be retrieved. Can be any valid Go type.
|
||||||
|
//
|
||||||
|
// Methods:
|
||||||
|
// - GetValue(name string) T: Returns a value of type T associated with the given name.
|
||||||
|
type (
|
||||||
|
GNameValueGetter[T any] interface {
|
||||||
|
GetValue(name string) T
|
||||||
|
}
|
||||||
|
|
||||||
|
// GNameValueGetterFnc is a function type that implements GNameValueGetter.
|
||||||
|
// It allows for creating value getters from simple functions, following
|
||||||
|
// the adapter pattern.
|
||||||
|
//
|
||||||
|
// Type Parameters:
|
||||||
|
// - T: The type of value to be returned by the function.
|
||||||
|
//
|
||||||
|
// The function signature matches the GetValue method of GNameValueGetter:
|
||||||
|
// - Input: name string - The key to lookup the value
|
||||||
|
// - Output: T - The value associated with the name
|
||||||
|
GNameValueGetterFnc[T any] func(name string) T
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetValue implements the GNameValueGetter interface for GNameValueGetterFnc.
|
||||||
|
// It simply calls the function itself, allowing the function to be used
|
||||||
|
// wherever a GNameValueGetter is expected.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - name: The key to lookup the value
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - T: The value associated with the name
|
||||||
|
func (f GNameValueGetterFnc[T]) GetValue(name string) T { return f(name) }
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package g_vals
|
||||||
|
|
||||||
|
type (
|
||||||
|
// GKeyValueSetter defines a generic interface for storing values in a key-value store.
|
||||||
|
// The interface is parameterized with two type parameters:
|
||||||
|
// K: The key type, which must be comparable
|
||||||
|
// T: The value type, which can be any type
|
||||||
|
//
|
||||||
|
// This interface provides a single method for storing values with type safety
|
||||||
|
// and error handling.
|
||||||
|
GKeyValueSetter[K comparable, T any] interface {
|
||||||
|
// SetValue stores a value of type T associated with the given key.
|
||||||
|
// Returns an error if the operation fails.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - key: The key under which to store the value
|
||||||
|
// - value: The value to store
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - error: nil if successful, otherwise an error describing the failure
|
||||||
|
SetValue(key K, value T) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// GKeyValueSetterFnc is a function type that implements the GKeyValueSetter interface.
|
||||||
|
// It allows simple functions to be used as key-value setters without creating
|
||||||
|
// a full struct implementation.
|
||||||
|
//
|
||||||
|
// Type parameters:
|
||||||
|
// K: The key type, which must be comparable
|
||||||
|
// T: The value type, which can be any type
|
||||||
|
//
|
||||||
|
// This type enables functional programming patterns and easy adaptation
|
||||||
|
// of existing functions to the GKeyValueSetter interface.
|
||||||
|
GKeyValueSetterFnc[K comparable, T any] func(key K, value T) error
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetValue implements the GKeyValueSetter interface for the GKeyValueSetterFnc type.
|
||||||
|
// This method allows the function type to be used directly as a GKeyValueSetter.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - key: The key of type K under which to store the value
|
||||||
|
// - value: The value of type T to store
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - error: The result of calling the underlying function
|
||||||
|
func (f GKeyValueSetterFnc[K, T]) SetValue(key K, value T) error {
|
||||||
|
return f(key, value)
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package g_vals
|
||||||
|
|
||||||
|
// GValue is a generic container struct that wraps a single value of any type.
|
||||||
|
// It provides a simple way to store and retrieve values in a type-safe manner.
|
||||||
|
//
|
||||||
|
// Type Parameters:
|
||||||
|
// - T: The type of the contained value. Can be any valid Go type.
|
||||||
|
//
|
||||||
|
// Fields:
|
||||||
|
// - V: The stored value of type T
|
||||||
|
type GValue[T any] struct {
|
||||||
|
V T
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value returns the contained value of type T.
|
||||||
|
// This method provides a consistent way to access the wrapped value,
|
||||||
|
// following the getter pattern common in Go.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - T: The stored value
|
||||||
|
func (v GValue[T]) Value() T { return v.V }
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package g_vals
|
||||||
|
|
||||||
|
type (
|
||||||
|
// GValueGetter defines a generic interface for retrieving values.
|
||||||
|
// Unlike GKeyValueGetter, this interface is simpler and doesn't require a key.
|
||||||
|
// It's parameterized with a single type parameter T that can be any type.
|
||||||
|
//
|
||||||
|
// This interface is useful for:
|
||||||
|
// - Lazy value evaluation
|
||||||
|
// - Value providers
|
||||||
|
// - Deferred computation
|
||||||
|
// - Wrapping value sources
|
||||||
|
GValueGetter[T any] interface {
|
||||||
|
// GetValue retrieves a value of type T.
|
||||||
|
// This method represents a simple value retrieval operation
|
||||||
|
// without parameters.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - T: The retrieved value
|
||||||
|
GetValue() T
|
||||||
|
}
|
||||||
|
|
||||||
|
// GValueGetterFnc is a function type that implements the GValueGetter interface.
|
||||||
|
// It allows simple functions to be used as value getters without creating
|
||||||
|
// a full struct implementation.
|
||||||
|
//
|
||||||
|
// Type parameters:
|
||||||
|
// T: The type of value to be retrieved
|
||||||
|
//
|
||||||
|
// This type enables functional programming patterns and easy creation
|
||||||
|
// of value providers from simple functions.
|
||||||
|
GValueGetterFnc[T any] func() T
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetValue implements the GValueGetter interface for the GValueGetterFnc type.
|
||||||
|
// This method allows the function type to be used directly as a GValueGetter.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - T: The result of calling the underlying function
|
||||||
|
func (f GValueGetterFnc[T]) GetValue() T {
|
||||||
|
return f()
|
||||||
|
}
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package g_vals
|
||||||
|
|
||||||
|
// Package g_vals provides generic interfaces for value provision operations.
|
||||||
|
|
||||||
|
type (
|
||||||
|
// GValueProvider defines a generic interface for providing values.
|
||||||
|
// It represents a source of values of type T, similar to GValueGetter
|
||||||
|
// but with a more specific semantic meaning of "providing" rather than
|
||||||
|
// "getting" values.
|
||||||
|
//
|
||||||
|
// Type parameters:
|
||||||
|
// T: The type of value to be provided, can be any type
|
||||||
|
//
|
||||||
|
// This interface is useful for:
|
||||||
|
// - Factory patterns
|
||||||
|
// - Lazy value generation
|
||||||
|
// - Dynamic value creation
|
||||||
|
// - Dependency injection
|
||||||
|
// - Value computation
|
||||||
|
GValueProvider[T any] interface {
|
||||||
|
// Value returns a value of type T.
|
||||||
|
// This method represents the provision of a value, which could be:
|
||||||
|
// - A computed value
|
||||||
|
// - A generated instance
|
||||||
|
// - A cached result
|
||||||
|
// - A factory-created object
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - T: The provided value
|
||||||
|
Value() T
|
||||||
|
}
|
||||||
|
|
||||||
|
// GValueProviderFnc is a function type that implements the GValueProvider interface.
|
||||||
|
// It allows simple functions to be used as value providers without creating
|
||||||
|
// a full struct implementation.
|
||||||
|
//
|
||||||
|
// Type parameters:
|
||||||
|
// T: The type of value to be provided
|
||||||
|
//
|
||||||
|
// This type enables functional programming patterns and easy creation
|
||||||
|
// of value providers from simple functions.
|
||||||
|
GValueProviderFnc[T any] func() T
|
||||||
|
)
|
||||||
|
|
||||||
|
// Value implements the GValueProvider interface for the GValueProviderFnc type.
|
||||||
|
// This method allows the function type to be used directly as a GValueProvider.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - T: The result of calling the underlying function
|
||||||
|
func (f GValueProviderFnc[T]) Value() T {
|
||||||
|
return f()
|
||||||
|
}
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package g_vals
|
||||||
|
|
||||||
|
// Package g_vals provides generic interfaces for value manipulation operations.
|
||||||
|
|
||||||
|
type (
|
||||||
|
// GValueSetter defines a generic interface for setting values.
|
||||||
|
// It provides a simple, type-safe way to store or update values
|
||||||
|
// without the complexity of key-value operations.
|
||||||
|
//
|
||||||
|
// Type parameters:
|
||||||
|
// T: The type of value to be set, can be any type
|
||||||
|
//
|
||||||
|
// This interface is useful for:
|
||||||
|
// - Value containers
|
||||||
|
// - State updaters
|
||||||
|
// - Configuration setters
|
||||||
|
// - Property writers
|
||||||
|
GValueSetter[T any] interface {
|
||||||
|
// SetValue updates or stores a value of type T.
|
||||||
|
// This method represents a simple value setting operation.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - value: The value of type T to be stored or updated
|
||||||
|
SetValue(T)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GValueSetterFnc is a function type that implements the GValueSetter interface.
|
||||||
|
// It allows simple functions to be used as value setters without creating
|
||||||
|
// a full struct implementation.
|
||||||
|
//
|
||||||
|
// Type parameters:
|
||||||
|
// T: The type of value to be set
|
||||||
|
//
|
||||||
|
// This type enables functional programming patterns and easy creation
|
||||||
|
// of value setters from simple functions.
|
||||||
|
GValueSetterFnc[T any] func(T)
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetValue implements the GValueSetter interface for the GValueSetterFnc type.
|
||||||
|
// This method allows the function type to be used directly as a GValueSetter.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - value: The value of type T to be set
|
||||||
|
func (f GValueSetterFnc[T]) SetValue(value T) {
|
||||||
|
f(value)
|
||||||
|
}
|
||||||
@ -0,0 +1,227 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Active-GO Framework
|
||||||
|
// Copyright (c) 2024 ActiveThing (https://activething.com)
|
||||||
|
// Author: Juan V. Navarro juanvnl@activething.com
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package vals
|
||||||
|
|
||||||
|
import (
|
||||||
|
"core/vals/g_vals"
|
||||||
|
"reflect"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
|
||||||
|
// ValueProvider defines an interface for providing any type of value
|
||||||
|
ValueProvider = g_vals.GValueProvider[any]
|
||||||
|
|
||||||
|
// ValueProviderFnc is a function implementation of ValueProvider
|
||||||
|
ValueProviderFnc = g_vals.GValueProviderFnc[any]
|
||||||
|
|
||||||
|
// ValueGetter defines an interface for getting any type of value
|
||||||
|
ValueGetter = g_vals.GValueGetter[any]
|
||||||
|
|
||||||
|
// ValueGetterFnc is a function implementation of ValueGetter
|
||||||
|
ValueGetterFnc = g_vals.GValueGetterFnc[any]
|
||||||
|
|
||||||
|
// ValueSetter defines an interface for setting any type of value
|
||||||
|
ValueSetter = g_vals.GValueSetter[any]
|
||||||
|
|
||||||
|
// ValueSetterFnc is a function implementation of ValueSetter
|
||||||
|
ValueSetterFnc = g_vals.GValueSetterFnc[any]
|
||||||
|
|
||||||
|
// KeyValueGetter is a type alias for the generic GKeyValueGetter interface
|
||||||
|
// specialized for any key and value types. It defines the read operations
|
||||||
|
// that can be performed on a key-value store.
|
||||||
|
//
|
||||||
|
// The interface allows for type-safe value retrieval while maintaining
|
||||||
|
// flexibility through the use of 'any' type parameters.
|
||||||
|
KeyValueGetter = g_vals.GKeyValueGetter[any, any]
|
||||||
|
|
||||||
|
// KeyValueSetter is a type alias for the generic GKeyValueSetter interface
|
||||||
|
// specialized for any key and value types. It defines the write operations
|
||||||
|
// that can be performed on a key-value store.
|
||||||
|
//
|
||||||
|
// The interface allows for type-safe value setting while maintaining
|
||||||
|
// flexibility through the use of 'any' type parameters.
|
||||||
|
KeyValueSetter = g_vals.GKeyValueSetter[any, any]
|
||||||
|
)
|
||||||
|
|
||||||
|
// AsValue extracts the actual value from various types of value containers.
|
||||||
|
// It handles nil values, value providers, getters, basic types, and functions.
|
||||||
|
//
|
||||||
|
// The function will:
|
||||||
|
// - Return nil for nil input
|
||||||
|
// - Call Value() for ValueProvider
|
||||||
|
// - Call GetValue() for ValueGetter
|
||||||
|
// - Return the value directly for basic types and their slices
|
||||||
|
// - Execute functions that take no parameters and return one value
|
||||||
|
// - Use reflection for generic functions with matching signature
|
||||||
|
// - Return the original object if no other case matches
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - object: any type of value or value container
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - the extracted or computed value
|
||||||
|
func AsValue(object any) any {
|
||||||
|
if object == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
switch obj := object.(type) {
|
||||||
|
case ValueProvider:
|
||||||
|
return obj.Value()
|
||||||
|
case ValueGetter:
|
||||||
|
return obj.GetValue()
|
||||||
|
// Basic types (returned directly)
|
||||||
|
case string, bool,
|
||||||
|
int, int8, int16, int32, int64,
|
||||||
|
uint, uint8, uint16, uint32, uint64,
|
||||||
|
float32, float64, complex64, complex128,
|
||||||
|
[]string, []bool,
|
||||||
|
[]int, []int8, []int16, []int32, []int64,
|
||||||
|
[]uint, []uint8, []uint16, []uint32, []uint64,
|
||||||
|
[]float32, []float64,
|
||||||
|
[]complex64, []complex128,
|
||||||
|
map[string]string, map[string]any,
|
||||||
|
map[string]int, map[int]string, map[int]any,
|
||||||
|
time.Time, *time.Time, time.Duration, *time.Duration,
|
||||||
|
error, chan string, chan int, chan bool, chan any:
|
||||||
|
return obj
|
||||||
|
// Common function types
|
||||||
|
case func() any:
|
||||||
|
return obj()
|
||||||
|
case func() string:
|
||||||
|
return obj()
|
||||||
|
case func() int:
|
||||||
|
return obj()
|
||||||
|
case func() uint:
|
||||||
|
return obj()
|
||||||
|
case func() float64:
|
||||||
|
return obj()
|
||||||
|
case func() bool:
|
||||||
|
return obj()
|
||||||
|
case func() error:
|
||||||
|
return obj()
|
||||||
|
default:
|
||||||
|
// Use reflection for generic functions
|
||||||
|
rv := reflect.ValueOf(object)
|
||||||
|
if rv.Kind() == reflect.Func && rv.Type().NumOut() == 1 && rv.Type().NumIn() == 0 {
|
||||||
|
return rv.Call(nil)[0].Interface()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Return the object directly if no other case matches
|
||||||
|
return object
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsValueProvider wraps an object into a ValueProvider interface.
|
||||||
|
// It's a convenience wrapper around CheckValueProvider that ignores the boolean return value.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - object: any value to be wrapped as a ValueProvider
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - a ValueProvider that will return the wrapped value
|
||||||
|
func AsValueProvider(object any) (prov ValueProvider) {
|
||||||
|
prov, _ = CheckValueProvider(object)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckValueProvider creates a ValueProvider from any value and indicates if the value
|
||||||
|
// is a natural provider (true) or was wrapped (false).
|
||||||
|
//
|
||||||
|
// A natural provider is:
|
||||||
|
// - An existing ValueProvider
|
||||||
|
// - A ValueGetter
|
||||||
|
// - A function returning a value
|
||||||
|
//
|
||||||
|
// The function handles:
|
||||||
|
// - nil values
|
||||||
|
// - Basic types and their slices
|
||||||
|
// - Common map types
|
||||||
|
// - Time-related types
|
||||||
|
// - Error types
|
||||||
|
// - Channel types
|
||||||
|
// - Common function types
|
||||||
|
// - Generic functions through reflection
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - object: any value to be converted to a ValueProvider
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - ValueProvider: a provider that will return the value
|
||||||
|
// - bool: true if the object was naturally a provider, false if it was wrapped
|
||||||
|
func CheckValueProvider(object any) (ValueProvider, bool) {
|
||||||
|
if object == nil {
|
||||||
|
return ValueProviderFnc(func() any { return nil }), true
|
||||||
|
}
|
||||||
|
switch obj := object.(type) {
|
||||||
|
case ValueProvider:
|
||||||
|
return obj, true
|
||||||
|
case ValueGetter:
|
||||||
|
return ValueProviderFnc(obj.GetValue), true
|
||||||
|
// Basic types and collections (wrapped as providers)
|
||||||
|
case string, bool,
|
||||||
|
int, int8, int16, int32, int64,
|
||||||
|
uint, uint8, uint16, uint32, uint64,
|
||||||
|
float32, float64,
|
||||||
|
complex64, complex128,
|
||||||
|
[]string, []bool,
|
||||||
|
[]int, []int8, []int16, []int32, []int64,
|
||||||
|
[]uint, []uint8, []uint16, []uint32, []uint64,
|
||||||
|
[]float32, []float64,
|
||||||
|
[]complex64, []complex128,
|
||||||
|
map[string]string,
|
||||||
|
map[string]int, map[int]string,
|
||||||
|
map[string]any,
|
||||||
|
map[int]any,
|
||||||
|
time.Time, *time.Time,
|
||||||
|
time.Duration, *time.Duration,
|
||||||
|
error,
|
||||||
|
chan string, chan int, chan bool,
|
||||||
|
chan any:
|
||||||
|
return ValueProviderFnc(func() any { return obj }), false
|
||||||
|
// Common function types (natural providers)
|
||||||
|
case func() string:
|
||||||
|
return ValueProviderFnc(func() any { return obj() }), true
|
||||||
|
case func() int:
|
||||||
|
return ValueProviderFnc(func() any { return obj() }), true
|
||||||
|
case func() uint:
|
||||||
|
return ValueProviderFnc(func() any { return obj() }), true
|
||||||
|
case func() float64:
|
||||||
|
return ValueProviderFnc(func() any { return obj() }), true
|
||||||
|
case func() error:
|
||||||
|
return ValueProviderFnc(func() any { return obj() }), true
|
||||||
|
case func() any:
|
||||||
|
return ValueProviderFnc(obj), true
|
||||||
|
default:
|
||||||
|
// Handle generic functions through reflection
|
||||||
|
rv := reflect.ValueOf(object)
|
||||||
|
if rv.Kind() == reflect.Func && rv.Type().NumOut() == 1 && rv.Type().NumIn() == 0 {
|
||||||
|
return ValueProviderFnc(func() any { return rv.Call(nil)[0].Interface() }), true
|
||||||
|
}
|
||||||
|
return ValueProviderFnc(func() any { return object }), false
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in new issue