specify

package module
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Mar 21, 2026 License: MIT Imports: 0 Imported by: 0

README

Specify

Go Reference

This library allows for abstracted business for validating conditions are met using the Specification Pattern.

The benefits of using this library are:

  • Conditional Logic can be abstracted into unit testable methods.
  • Abstractions provide a deeper insight and intent into what is being checked.
  • Conditions can be chained together to form higher order rules while remaining testable.
  • Increases the reason about the business logic

Since conditions can be appended to and chained together, it means that logic implementation is not repeated and can be easily refactored in future updates to the project.

Usage

An example of where Specify can shine is when working with various external packages or systems that may have the ability to express conditional statements. The example below makes the assumption that this service has users stored inside a sql dabase and there are some helper methods attached to the account that abstract some of the data access for us.

import (
    "database/sql"

    "github.com/MovieStoreGuy/specify"
)

func AccountExists(db *sql.DB) specify.ConditionFunc[*AccountDetails] {
    return specify.ConditionFunc[*AccountDetails](func(account *AccountDetails) (bool, error){ 
        rows, err := db.query("valid query here...", account.Username())
        if err != nil {
            return false, err
        }
        return len(rows) == 1, nil
    })
}

func AccountSuspended() specify.Condition[*AccountDetails] {
    return specify.ConditionFunc[*AccountDetails](func(account *AccountDetails) (bool, error){ 
        return account.Deactivated() || time.Now().Sub(account.LastAcessed()) > 30 * 24 * time.Hour
    })
}

func AccountAdmin() specify.Condition[*AccountDetails] {
    return specify.ConditionFunc[*AccountDetails](func(account *AccountDetails) (bool, error){
        return account.Flags() & ADMIN_FLAG == ADMIN_FLAG, nil
    })
}


// IsValidAccount ensure that the account exists first and validates that the account is not suspended
// by chaining the above functions.
func IsValidAccount(db *sql.DB) specify.Condition[*AccountDetails] {
    return AccountExists(db).And(specify.Not(AccountSuspended()))
}

// IsValidAdmin extends the `IsValidAccount` by appending an 
// additional condition to verify admin flags are set.
func IsValidAdmin(db *sql.DB) specify.Condition[*AccountDetails] {
    return specify.And(IsValidAccount(db), AdminAccount())
}

Examples

Please see Examples for potential ideas on how to use this.

Documentation

Overview

Package Specify is a library that is intended to provide a layer of abstraction using the Specification Pattern to allow for programticly defining conditions and allow for chaining.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Condition

type Condition[T any] interface {
	// Check evaluates the defined condition against the provided value [T],
	// in the event an error is returned, the result value should be ignored.
	Check(input T) (result bool, err error)
}

Condition provides an abstraction to define conditions programatically that will be lazily evaluated once once it is checked.

func And

func And[T any](a, b Condition[T], conditions ...Condition[T]) Condition[T]

And lazily performs the logical and which will stop once false result is returned from a provided condition.

func NewCondition added in v0.0.3

func NewCondition[T any](check func(input T) (bool, error)) Condition[T]

func Not

func Not[T any](cond Condition[T]) Condition[T]

Not performs the logical not and inverts the result.

func Or

func Or[T any](a, b Condition[T], conditions ...Condition[T]) Condition[T]

Or lazily performs the logical or which returns one the first true result.

func Xor

func Xor[T any](a, b Condition[T], more ...Condition[T]) Condition[T]

Xor performs the logical xor which only returns true if one condition is true

type ConditionAnd

type ConditionAnd[T any] interface {
	Condition[T]

	// And is an alias for `specify.And(this, b, others...)`
	And(b Condition[T], others ...Condition[T]) Condition[T]
}

ConditionAnd is an extension to condition to allow for natural reading condition statements when using `ConditionFunc`.

type ConditionFunc

type ConditionFunc[T any] func(input T) (bool, error)

ConditionFunc implements the Condition[T] type and allows for simplified lambda abstractions.

func (ConditionFunc[T]) And

func (cond ConditionFunc[T]) And(b Condition[T], others ...Condition[T]) Condition[T]

func (ConditionFunc[T]) Check

func (cond ConditionFunc[T]) Check(input T) (bool, error)

func (ConditionFunc[T]) Or

func (cond ConditionFunc[T]) Or(b Condition[T], others ...Condition[T]) Condition[T]

func (ConditionFunc[T]) Xor

func (cond ConditionFunc[T]) Xor(b Condition[T]) Condition[T]

type ConditionOr

type ConditionOr[T any] interface {
	Condition[T]

	// Or is an alias for `specify.Or(this, b, others ...)`
	Or(b Condition[T], others ...Condition[T]) Condition[T]
}

ConditionOr is an extension to condition to allow for natural reading condition statements when using `ConditionFunc`.

type ConditionXor

type ConditionXor[T any] interface {
	Condition[T]

	// Xor is an alias for `specify.Xor(this, b)`
	Xor(b Condition[T]) Condition[T]
}

ConditionXor is an extension to condition to allow for natural reading condition statements when using `ConditionFunc`.

Directories

Path Synopsis
examples
validator command
internal

Jump to

Keyboard shortcuts

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