summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-24 13:50:53 +0300
committerPaul Buetow <paul@buetow.org>2026-05-24 13:50:53 +0300
commit6d90062cb1b3f00f6fc1e5db942a153580b196ee (patch)
tree9a87e6e1e1f8fa49f4ec3caf312d0f09301db10b
parentedef5bf414f60704f2a18c0d41d4464f2fd7d2c0 (diff)
rpn: decouple RPN from concrete *Operations type (task aj)
Define OperationsProvider interface composed of focused sub-interfaces (ModeController, MetricCommander, CustomMetricManager) plus the existing StackOperator. Change RPN.ops from *Operations to OperationsProvider so the high-level RPN module depends on abstractions, not the concrete type (DIP). Add compile-time assertions for the new interfaces in operations.go.
-rw-r--r--internal/rpn/operations.go14
-rw-r--r--internal/rpn/operations_interfaces.go45
-rw-r--r--internal/rpn/rpn_state.go2
3 files changed, 50 insertions, 11 deletions
diff --git a/internal/rpn/operations.go b/internal/rpn/operations.go
index ca57a42..e5cc891 100644
--- a/internal/rpn/operations.go
+++ b/internal/rpn/operations.go
@@ -23,11 +23,15 @@ var (
_ LogarithmicOperator = (*Operations)(nil)
_ MetricOperator = (*Operations)(nil)
_ BooleanOperator = (*Operations)(nil)
- _ HyperOperator = (*Operations)(nil)
- _ StackOperator = (*Operations)(nil)
- _ VariableOperator = (*Operations)(nil)
- _ ConstantOperator = (*Operations)(nil)
- _ PowerIntOperator = (*Operations)(nil)
+ _ HyperOperator = (*Operations)(nil)
+ _ StackOperator = (*Operations)(nil)
+ _ VariableOperator = (*Operations)(nil)
+ _ ConstantOperator = (*Operations)(nil)
+ _ PowerIntOperator = (*Operations)(nil)
+ _ ModeController = (*Operations)(nil)
+ _ MetricCommander = (*Operations)(nil)
+ _ CustomMetricManager = (*Operations)(nil)
+ _ OperationsProvider = (*Operations)(nil)
)
// NewOperations creates a new Operations instance with the given variable store.
diff --git a/internal/rpn/operations_interfaces.go b/internal/rpn/operations_interfaces.go
index 6a543b9..7542993 100644
--- a/internal/rpn/operations_interfaces.go
+++ b/internal/rpn/operations_interfaces.go
@@ -76,13 +76,48 @@ type PowerIntOperator interface {
FastPower(stack *Stack) error
}
+// ModeController defines the interface for calculation mode and prefix mode control.
+type ModeController interface {
+ SetMode(CalculationMode)
+ GetMode() CalculationMode
+ SetPrefixMode(PrefixMode)
+ GetPrefixMode() PrefixMode
+}
+
+// MetricCommander defines the interface for metric query commands.
+type MetricCommander interface {
+ MetricRegistry() *MetricRegistry
+ MetricShow(stack *Stack) (string, error)
+ MetricList(stack *Stack) (string, error)
+ MetricCategory(stack *Stack, categoryName string) (string, error)
+ MetricCompatible(stack *Stack) (string, error)
+}
+
+// CustomMetricManager defines the interface for custom metric operations.
+type CustomMetricManager interface {
+ CustomShow(stack *Stack, name string) (string, error)
+ CustomList(stack *Stack) (string, error)
+ CustomDefine(name string, factor float64, category string) error
+ CustomUndefine(name string) error
+}
+
+// OperationsProvider combines all interfaces that RPN needs from Operations.
+// RPN depends on this interface (DIP) rather than the concrete *Operations type.
+type OperationsProvider interface {
+ ModeController
+ StackOperator
+ MetricCommander
+ CustomMetricManager
+ SetConstants(ConstantsProvider)
+}
+
// Operator implementations are split across focused sub-interfaces
// (ArithmeticOperator, LogarithmicOperator, MetricOperator, BooleanOperator,
// HyperOperator, StackOperator, VariableOperator, ConstantOperator,
// PowerIntOperator) for clarity.
-// The combined Operator interface was removed — RPN is the sole client
-// and Operations is the sole implementor, so the interface added
-// indirection without practical benefit (ISP).
//
-// Each sub-interface is satisfied by *Operations, verified by compile-time
-// checks in operations.go.
+// The OperationsProvider interface is the combined interface that RPN depends
+// on, satisfying DIP by decoupling RPN from the concrete *Operations type.
+//
+// Each sub-interface and OperationsProvider is satisfied by *Operations,
+// verified by compile-time checks in operations.go.
diff --git a/internal/rpn/rpn_state.go b/internal/rpn/rpn_state.go
index 458973f..e99a02d 100644
--- a/internal/rpn/rpn_state.go
+++ b/internal/rpn/rpn_state.go
@@ -14,7 +14,7 @@ type RPN struct {
mu sync.RWMutex
vars VariableStore
consts ConstantsProvider
- ops *Operations
+ ops OperationsProvider
opRegistry *OperatorRegistry
assignHandler *assignmentHandler
maxStack int