first commit

main
Juan V. Navarro 2 years ago
commit cbcc27f1a3

8
.idea/.gitignore vendored

@ -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
}
}

@ -0,0 +1,3 @@
module Active-GO
go 1.22

@ -0,0 +1,6 @@
go 1.22
use (
.
core
)
Loading…
Cancel
Save

Powered by TurnKey Linux.