Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/vendor
_*
go.sum
go.sum
go.work
vendor/
_*
benchmark*
.claude*
claude*
CLAUDE*
coverage*
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,26 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- **Minor**: feature additions, removal of deprecated features
- **Patch**: bug fixes, backward compatible protobuf model changes, etc.

# v2.2.0 - 2026-05-23
#### Added
* `model.Model.GetData()` — returns snapshots of the data set and key/index maps; implementations must not expose internal storage directly
* `model.Model.Reverse()` — reverses the order of the data store
* `sorter.SortByValue` — zero-value `SortFlag`; type-stratified sort (nil < bool < numeric < string < other); now the default sort behavior
* `sorter.SortAsc`, `SortDesc`, `SortAsString`, `SortReverse` — explicit bitflag sort options
* `.gitignore`

#### Changed
* `model.ModelTypeHash` / `model.ModelTypeList` renamed to `model.HASH` / `model.LIST`; order swapped so `HASH` is the zero/iota value
* `model.Model.Filter` callback signature changed from `func(Value) Model` to `func(Value) bool`
* `model.Model.Map` callback signature changed from `func(Value) Model` to `func(Value) Value`
* `model.Model.Reduce` callback signature changed from `func(Value) bool` to `func(carry, cur Value) Value` (standard fold semantics)
* `model.Model.SetID` now returns `error`
* `sorter.SortFlag` underlying type changed from `int` to `uint`
* `sorter.Sorter.Reverse` signature changed from `Reverse(SortFlag) error` to `Reverse() error`

#### Fixed
* `errors/error.go` package declaration corrected from `package error` to `package errors`

# v2.1.0 - 2020-05-30
#### Added
* `Caller` package
Expand Down
2 changes: 1 addition & 1 deletion errors/error.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package error
package errors

import (
"github.com/bdlm/std/v2/caller"
Expand Down
55 changes: 43 additions & 12 deletions model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ package model
type ModelType int

const (
// ModelTypeList causes the model to behave as a list (keys are unsigned,
// contiguous integers beginning at 0).
ModelTypeList ModelType = iota
// ModelTypeHash causes the model to behave as a hash (keys are strings,
// HASH causes the model to behave as a hash (keys are strings,
// order is static).
ModelTypeHash
HASH ModelType = iota

// LIST causes the model to behave as a list (keys are unsigned,
// contiguous integers beginning at 0).
LIST
)
Comment thread
mkenney marked this conversation as resolved.

// Model is a list or a map of Values.
Expand All @@ -23,10 +24,23 @@ type Model interface {
Delete(key interface{}) error
// Filter filters elements of the data using a callback function and
// returns the result.
Filter(callback func(Value) Model) Model
Filter(callback func(Value) bool) Model
// Get returns the specified data value in this model.
Get(key interface{}) (Value, error)
// GetID returns returns this model's id.
// GetData returns snapshots of the current data set and indexes.
//
// Implementations must not expose internal slice or map storage directly;
// the returned slice and maps must be safe for the caller to read and
// modify without affecting the model's internal state.
//
// The return values are:
// - data: a snapshot of the model's values in model order.
// - keyToIndex: a snapshot of hash keys to indexes for HASH models; nil
// for LIST models.
// - indexToKey: a snapshot of indexes to hash keys for HASH models; nil
// for LIST models.
GetData() ([]interface{}, map[string]int, map[int]string)
// GetID returns this model's id.
GetID() interface{}
// GetType returns the model type.
GetType() ModelType
Expand All @@ -36,22 +50,39 @@ type Model interface {
Lock()
// Map applies a callback to all elements in this model and returns the
// result.
Map(callback func(Value) Model) Model
Map(callback func(Value) Value) Model
// Merge merges data from any Model into this Model.
Merge(Model) error
// Push a value to the end of the internal data store.
Push(value interface{}) error
// Reduce iteratively reduces the data set to a single value using a
// callback function and returns the result.
Reduce(callback func(Value) bool) Value
// Reduce iteratively reduces the data to a single value using a callback
// function and returns the result.
//
// The callback function takes two `Value` arguments, the first being the
// carry value from the previous iteration (or the first element for the
// first iteration) and the second being the current element. The callback
// returns a `Value` which becomes the carry value for the next iteration.
// After all iterations, Reduce returns the final carry value.
Comment thread
mkenney marked this conversation as resolved.
//
// For a non-empty model, the first element is used as the initial carry,
// so the callback is first invoked with that carry and the second
// element. For an empty model, Reduce returns nil and does not invoke the
// callback.
Reduce(callback func(carry, cur Value) Value) Value
// Set stores a value in the internal data store. All values must be
// identified by key.
Set(key interface{}, value interface{}) error
// SetData replaces the current data stored in the model with the
// provided data.
SetData(data interface{}) error
// Reverse reverses the order of the data store.
Reverse() error
// SetID sets this Model's identifier property.
Comment thread
mkenney marked this conversation as resolved.
SetID(id interface{})
//
// It returns an error if the model is read-only (for example, after
// Lock has been called) or if id is invalid or of an unsupported type
// for the implementation.
SetID(id interface{}) error
// SetType sets the model type. If any data is stored in this model,
// this property becomes read-only.
SetType(typ ModelType) error
Expand Down
25 changes: 21 additions & 4 deletions sorter/sorter.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,34 @@
package sorter

// SortFlag provides a type for sort flags
type SortFlag int
type SortFlag uint

const (
// SortByKey - sort hash data by key
SortByKey SortFlag = iota
// SortByValue - sort data by value using type-stratified comparison:
// nil < bool < numeric < string < other. This is the default/zero value.
SortByValue SortFlag = 0

// SortByKey - sort hash data by key.
SortByKey SortFlag = 1 << 0

// SortAsc - sort data in ascending order. This is the default.
SortAsc SortFlag = 1 << 1

// SortDesc - sort data in descending order.
SortDesc SortFlag = 1 << 2

// SortAsString - when sorting data use string comparison via cast. This is
// a tiebreak for SortByValue and the default for SortByKey.
SortAsString SortFlag = 1 << 3

// SortReverse - reverse the order of the data set after sorting.
SortReverse SortFlag = 1 << 4
)

// Sorter describes a sorter.
type Sorter interface {
// Reverse reverses the order of the data set.
Reverse(SortFlag) error
Reverse() error
// Sort sorts the model data.
Sort(SortFlag) error
// Len returns the number of items stored in this model.
Expand Down
Loading