sortsmith 0.2.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +146 -1
- data/README.md +269 -60
- data/flake.lock +3 -3
- data/flake.nix +11 -5
- data/lib/sortsmith/core_ext/enumerable.rb +109 -0
- data/lib/sortsmith/sorter.rb +692 -99
- data/lib/sortsmith/version.rb +4 -1
- data/lib/sortsmith.rb +49 -2
- metadata +4 -9
- data/Steepfile +0 -8
- data/lib/sortsmith/step.rb +0 -17
- data/sig/sortsmith/sorter.rbs +0 -107
- data/sig/sortsmith/step.rbs +0 -28
- data/sig/sortsmith/version.rbs +0 -3
- data/sig/sortsmith.rbs +0 -4
data/lib/sortsmith/version.rb
CHANGED
data/lib/sortsmith.rb
CHANGED
@@ -1,9 +1,56 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "sortsmith/sorter"
|
4
|
-
require_relative "sortsmith/step"
|
5
3
|
require_relative "sortsmith/version"
|
4
|
+
require_relative "sortsmith/core_ext/enumerable"
|
5
|
+
require_relative "sortsmith/sorter"
|
6
6
|
|
7
|
+
##
|
8
|
+
# Sortsmith provides a flexible, chainable API for sorting Ruby collections.
|
9
|
+
#
|
10
|
+
# The gem extends Ruby's built-in {Enumerable} module to provide an intuitive
|
11
|
+
# sorting interface that reads like natural language and supports complex
|
12
|
+
# sorting operations through method chaining.
|
13
|
+
#
|
14
|
+
# @example Basic usage
|
15
|
+
# users = ["Charlie", "alice", "Bob"]
|
16
|
+
# users.sort_by.downcase.sort
|
17
|
+
# # => ["alice", "Bob", "Charlie"]
|
18
|
+
#
|
19
|
+
# @example Hash sorting
|
20
|
+
# users = [
|
21
|
+
# { name: "Charlie", age: 25 },
|
22
|
+
# { name: "alice", age: 30 },
|
23
|
+
# { name: "Bob", age: 20 }
|
24
|
+
# ]
|
25
|
+
# users.sort_by.dig(:name).insensitive.sort
|
26
|
+
# # => sorted by name, case-insensitive
|
27
|
+
#
|
28
|
+
# @example Complex chaining
|
29
|
+
# users.sort_by.dig(:name, indifferent: true).downcase.desc.sort
|
30
|
+
# # => Extract name (works with both string/symbol keys), downcase, descending
|
31
|
+
#
|
32
|
+
# @see Sortsmith::Sorter The main sorting interface
|
33
|
+
# @see Enumerable#sort_by The extended sort_by method
|
34
|
+
#
|
35
|
+
# @author Bryan "itsthedevman"
|
36
|
+
# @since 0.1.0
|
37
|
+
#
|
7
38
|
module Sortsmith
|
39
|
+
##
|
40
|
+
# Base error class for all Sortsmith-related exceptions.
|
41
|
+
#
|
42
|
+
# This provides a namespace for any custom errors that may be raised
|
43
|
+
# during sorting operations, making it easier to rescue Sortsmith-specific
|
44
|
+
# issues without catching unrelated StandardError instances.
|
45
|
+
#
|
46
|
+
# @example Rescuing Sortsmith errors
|
47
|
+
# begin
|
48
|
+
# complex_sort_operation
|
49
|
+
# rescue Sortsmith::Error => e
|
50
|
+
# handle_sorting_error(e)
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# @since 0.1.0
|
54
|
+
#
|
8
55
|
class Error < StandardError; end
|
9
56
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sortsmith
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bryan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-08-03 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Sortsmith provides a flexible, chainable API for sorting Ruby collections.
|
14
14
|
It supports sorting by object keys, methods, case sensitivity, and custom transformations.
|
@@ -25,17 +25,12 @@ files:
|
|
25
25
|
- LICENSE.txt
|
26
26
|
- README.md
|
27
27
|
- Rakefile
|
28
|
-
- Steepfile
|
29
28
|
- flake.lock
|
30
29
|
- flake.nix
|
31
30
|
- lib/sortsmith.rb
|
31
|
+
- lib/sortsmith/core_ext/enumerable.rb
|
32
32
|
- lib/sortsmith/sorter.rb
|
33
|
-
- lib/sortsmith/step.rb
|
34
33
|
- lib/sortsmith/version.rb
|
35
|
-
- sig/sortsmith.rbs
|
36
|
-
- sig/sortsmith/sorter.rbs
|
37
|
-
- sig/sortsmith/step.rbs
|
38
|
-
- sig/sortsmith/version.rbs
|
39
34
|
homepage: https://github.com/itsthedevman/sortsmith
|
40
35
|
licenses:
|
41
36
|
- MIT
|
@@ -53,7 +48,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
53
48
|
requirements:
|
54
49
|
- - ">="
|
55
50
|
- !ruby/object:Gem::Version
|
56
|
-
version: '3.
|
51
|
+
version: '3.1'
|
57
52
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
53
|
requirements:
|
59
54
|
- - ">="
|
data/Steepfile
DELETED
data/lib/sortsmith/step.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Sortsmith
|
4
|
-
#
|
5
|
-
# Represents a step in the sorting process
|
6
|
-
#
|
7
|
-
class Step < Data.define(:type, :block)
|
8
|
-
TYPES = [
|
9
|
-
TRANSFORMATION = :transformation,
|
10
|
-
FILTER = :filter
|
11
|
-
].freeze
|
12
|
-
|
13
|
-
def perform(item)
|
14
|
-
block.call(item)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
data/sig/sortsmith/sorter.rbs
DELETED
@@ -1,107 +0,0 @@
|
|
1
|
-
module Sortsmith
|
2
|
-
interface _Sortable
|
3
|
-
def to_s: () -> String
|
4
|
-
def <=>: (self) -> Integer
|
5
|
-
end
|
6
|
-
|
7
|
-
class Sorter[Elem < _Sortable]
|
8
|
-
@enumerable: Enumerable[Elem]
|
9
|
-
|
10
|
-
@pipeline: Array[Step]
|
11
|
-
|
12
|
-
@direction: Symbol
|
13
|
-
|
14
|
-
#
|
15
|
-
# Creates a Sorter builder instance
|
16
|
-
#
|
17
|
-
# @param enumerable [Enumerable] The enumerable (Array, Hash) to sort
|
18
|
-
#
|
19
|
-
def initialize: (Enumerable[Elem] enumerable) -> void
|
20
|
-
|
21
|
-
#
|
22
|
-
# Finalizes the Sorter instance and sorts the enumerable
|
23
|
-
#
|
24
|
-
# @return [Enumerable] The sorted enumerable
|
25
|
-
#
|
26
|
-
def sort: () -> Enumerable[Elem]
|
27
|
-
|
28
|
-
#
|
29
|
-
# Adds a "filter" step to the sort pipeline.
|
30
|
-
# Filter steps are used to get data from the current item being sorted
|
31
|
-
# These are performed before transformation steps
|
32
|
-
#
|
33
|
-
# @param & [Proc] The block to execute
|
34
|
-
#
|
35
|
-
# @return [Self] The sorter instance
|
36
|
-
#
|
37
|
-
def add_filter: () { (untyped) -> untyped } -> self
|
38
|
-
|
39
|
-
#
|
40
|
-
# Adds a "transformation" step to the sort pipeline
|
41
|
-
# Transformation steps are used to transform data.
|
42
|
-
# These are performed after filter steps
|
43
|
-
#
|
44
|
-
# @param & [Proc] The block to execute
|
45
|
-
#
|
46
|
-
# @return [Self] The sorter instance
|
47
|
-
#
|
48
|
-
def add_transformation: () { (untyped) -> untyped } -> self
|
49
|
-
|
50
|
-
#
|
51
|
-
# Instructs the sorter to perform a fetch by key on the Hash being sorted
|
52
|
-
#
|
53
|
-
# @param key [String, Symbol, Any] The hash key to fetch
|
54
|
-
#
|
55
|
-
# @return [Self] The sorter instance
|
56
|
-
#
|
57
|
-
def by_key: ((String | Symbol | untyped) key) -> self
|
58
|
-
|
59
|
-
#
|
60
|
-
# Instructs the sorter to perform a method call on the object being sorted
|
61
|
-
#
|
62
|
-
# @param method [String, Symbol] The method name to call
|
63
|
-
#
|
64
|
-
# @return [Self] The sorter instance
|
65
|
-
#
|
66
|
-
def by_method: ((String | Symbol) method) -> self
|
67
|
-
|
68
|
-
alias by_attribute by_method
|
69
|
-
|
70
|
-
#
|
71
|
-
# Instructs the sorter to sort by a case insensitive value
|
72
|
-
#
|
73
|
-
# @return [Self] The sorter instance
|
74
|
-
#
|
75
|
-
def case_insensitive: () -> self
|
76
|
-
|
77
|
-
#
|
78
|
-
# Controls which direction the array will be sorted
|
79
|
-
#
|
80
|
-
# @return [Self] The sorter instance
|
81
|
-
#
|
82
|
-
def asc: () -> self
|
83
|
-
|
84
|
-
alias forward asc
|
85
|
-
|
86
|
-
#
|
87
|
-
# Controls which direction the array will be sorted
|
88
|
-
#
|
89
|
-
# @return [Self] The sorter instance
|
90
|
-
#
|
91
|
-
def desc: () -> self
|
92
|
-
|
93
|
-
alias reverse desc
|
94
|
-
|
95
|
-
private
|
96
|
-
|
97
|
-
def add_step: (type: Symbol) { (untyped) -> untyped } -> self
|
98
|
-
|
99
|
-
def select_filter_steps: () -> Array[Step]
|
100
|
-
|
101
|
-
def select_transformation_steps: () -> Array[Step]
|
102
|
-
|
103
|
-
def type_priority: (untyped value) -> Integer
|
104
|
-
|
105
|
-
def apply_transformations: (Array[Step] steps, untyped value) -> untyped
|
106
|
-
end
|
107
|
-
end
|
data/sig/sortsmith/step.rbs
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
module Sortsmith
|
2
|
-
#
|
3
|
-
# Represents a step in the sorting process
|
4
|
-
#
|
5
|
-
class Step < ::Data
|
6
|
-
TYPES: ::Array[Symbol]
|
7
|
-
|
8
|
-
FILTER: Symbol
|
9
|
-
|
10
|
-
TRANSFORMATION: Symbol
|
11
|
-
|
12
|
-
attr_reader type: Symbol
|
13
|
-
|
14
|
-
attr_reader block: ^(untyped) -> untyped
|
15
|
-
|
16
|
-
def self.new: (Symbol type, untyped block) -> instance
|
17
|
-
| (type: Symbol, block: untyped) -> instance
|
18
|
-
|
19
|
-
def self.[]: (Symbol type, untyped block) -> instance
|
20
|
-
| (type: Symbol, block: untyped) -> instance
|
21
|
-
|
22
|
-
def self.members: () -> [ :type, :block ]
|
23
|
-
|
24
|
-
def members: () -> [ :type, :block ]
|
25
|
-
|
26
|
-
def perform: (untyped item) -> untyped
|
27
|
-
end
|
28
|
-
end
|
data/sig/sortsmith/version.rbs
DELETED
data/sig/sortsmith.rbs
DELETED