diff --git a/docs/api/state.md b/docs/api/state.md index 68755311..67ad69bc 100644 --- a/docs/api/state.md +++ b/docs/api/state.md @@ -1,18 +1,18 @@ # State Management -This document details the state management functionality provided by Fiber, a thread-safe global key-value store used to store application dependencies and runtime data. The implementation is based on Go's `sync.Map` ensuring concurrency safety. +This document details the state management functionality provided by Fiber, a thread-safe global key–value store used to store application dependencies and runtime data. The implementation is based on Go's `sync.Map`, ensuring concurrency safety. Below is the detailed description of all public methods and usage examples. ## State Type -`State` is a key-value store built on top of `sync.Map`. It allows storage and retrieval of dependencies and configurations in a Fiber application as well as thread-safe access to runtime data. +`State` is a key–value store built on top of `sync.Map`. It allows storage and retrieval of dependencies and configurations in a Fiber application as well as thread–safe access to runtime data. ### Definition ```go -// State is a key-value store for Fiber's app in order to be used as a global storage for the app's dependencies. -// It's a thread-safe implementation of a map[string]any, using sync.Map. +// State is a key–value store for Fiber's app, used as a global storage for the app's dependencies. +// It is a thread–safe implementation of a map[string]any, using sync.Map. type State struct { dependencies sync.Map } @@ -22,9 +22,10 @@ type State struct { ### Set -Set adds or updates a key-value pair in the State. +Set adds or updates a key–value pair in the State. -```go title="Signature" +```go +// Set adds or updates a key–value pair in the State. func (s *State) Set(key string, value any) ``` @@ -66,75 +67,12 @@ appName := app.State().MustGet("appName") fmt.Println("App Name:", appName) ``` -### GetString - -GetString retrieves a string value from the State. It returns the string and a boolean indicating successful type assertion. - -```go title="Signature" -func (s *State) GetString(key string) (string, bool) -``` - -**Usage Example:** - -```go -if appName, ok := app.State().GetString("appName"); ok { - fmt.Println("App Name:", appName) -} -``` - -### GetInt - -GetInt retrieves an integer value from the State. It returns the int and a boolean indicating successful type assertion. - -```go title="Signature" -func (s *State) GetInt(key string) (int, bool) -``` - -**Usage Example:** - -```go -if count, ok := app.State().GetInt("userCount"); ok { - fmt.Printf("User Count: %d\n", count) -} -``` - -### GetBool - -GetBool retrieves a boolean value from the State. It returns the bool and a boolean indicating successful type assertion. - -```go title="Signature" -func (s *State) GetBool(key string) (value, ok bool) -``` - -**Usage Example:** - -```go -if debug, ok := app.State().GetBool("debugMode"); ok { - fmt.Printf("Debug Mode: %v\n", debug) -} -``` - -### GetFloat64 - -GetFloat64 retrieves a float64 value from the State. It returns the float64 and a boolean indicating successful type assertion. - -```go title="Signature" -func (s *State) GetFloat64(key string) (float64, bool) -``` - -**Usage Example:** - -```go title="Signature" -if ratio, ok := app.State().GetFloat64("scalingFactor"); ok { - fmt.Printf("Scaling Factor: %f\n", ratio) -} -``` ### Has Has checks if a key exists in the State. -```go title="Signature" +```go title="Signature"s func (s *State) Has(key string) bool ``` @@ -148,7 +86,7 @@ if app.State().Has("appName") { ### Delete -Delete removes a key-value pair from the State. +Delete removes a key–value pair from the State. ```go title="Signature" func (s *State) Delete(key string) @@ -162,7 +100,7 @@ app.State().Delete("obsoleteKey") ### Reset -Reset resets the State by removing all keys. +Reset removes all keys from the State. ```go title="Signature" func (s *State) Reset() @@ -193,7 +131,8 @@ fmt.Println("State Keys:", keys) Len returns the number of keys in the State. -```go title="Signature" +```go +// Len returns the number of keys in the State. func (s *State) Len() int ``` @@ -203,13 +142,285 @@ func (s *State) Len() int fmt.Printf("Total State Entries: %d\n", app.State().Len()) ``` +### GetString + +GetString retrieves a string value from the State. It returns the string and a boolean indicating a successful type assertion. + +```go title="Signature" +func (s *State) GetString(key string) (string, bool) +``` + +**Usage Example:** + +```go +if appName, ok := app.State().GetString("appName"); ok { + fmt.Println("App Name:", appName) +} +``` + +### GetInt + +GetInt retrieves an integer value from the State. It returns the int and a boolean indicating a successful type assertion. + +```go title="Signature" +func (s *State) GetInt(key string) (int, bool) +``` + +**Usage Example:** + +```go +if count, ok := app.State().GetInt("userCount"); ok { + fmt.Printf("User Count: %d\n", count) +} +``` + +### GetBool + +GetBool retrieves a boolean value from the State. It returns the bool and a boolean indicating a successful type assertion. + +```go title="Signature" +func (s *State) GetBool(key string) (value, bool) +``` + +**Usage Example:** + +```go +if debug, ok := app.State().GetBool("debugMode"); ok { + fmt.Printf("Debug Mode: %v\n", debug) +} +``` + +### GetFloat64 + +GetFloat64 retrieves a float64 value from the State. It returns the float64 and a boolean indicating a successful type assertion. + +```go title="Signature" +func (s *State) GetFloat64(key string) (float64, bool) +``` + +**Usage Example:** + +```go title="Signature" +if ratio, ok := app.State().GetFloat64("scalingFactor"); ok { + fmt.Printf("Scaling Factor: %f\n", ratio) +} +``` + +### GetUint + +GetUint retrieves a `uint` value from the State. + +```go title="Signature" +func (s *State) GetUint(key string) (uint, bool) +``` + +**Usage Example:** + +```go +if val, ok := app.State().GetUint("maxConnections"); ok { + fmt.Printf("Max Connections: %d\n", val) +} +``` + +### GetInt8 + +GetInt8 retrieves an `int8` value from the State. + +```go title="Signature" +func (s *State) GetInt8(key string) (int8, bool) +``` + +**Usage Example:** + +```go +if val, ok := app.State().GetInt8("threshold"); ok { + fmt.Printf("Threshold: %d\n", val) +} +``` + +### GetInt16 + +GetInt16 retrieves an `int16` value from the State. + +```go title="Signature" +func (s *State) GetInt16(key string) (int16, bool) +``` + +**Usage Example:** + +```go +if val, ok := app.State().GetInt16("minValue"); ok { + fmt.Printf("Minimum Value: %d\n", val) +} +``` + +### GetInt32 + +GetInt32 retrieves an `int32` value from the State. + +```go title="Signature" +func (s *State) GetInt32(key string) (int32, bool) +``` + +**Usage Example:** + +```go +if val, ok := app.State().GetInt32("portNumber"); ok { + fmt.Printf("Port Number: %d\n", val) +} +``` + +### GetInt64 + +GetInt64 retrieves an `int64` value from the State. + +```go title="Signature" +func (s *State) GetInt64(key string) (int64, bool) +``` + +**Usage Example:** + +```go +if val, ok := app.State().GetInt64("fileSize"); ok { + fmt.Printf("File Size: %d\n", val) +} +``` + +### GetUint8 + +GetUint8 retrieves a `uint8` value from the State. + +```go title="Signature" +func (s *State) GetUint8(key string) (uint8, bool) +``` + +**Usage Example:** + +```go +if val, ok := app.State().GetUint8("byteValue"); ok { + fmt.Printf("Byte Value: %d\n", val) +} +``` + +### GetUint16 + +GetUint16 retrieves a `uint16` value from the State. + +```go title="Signature" +func (s *State) GetUint16(key string) (uint16, bool) +``` + +**Usage Example:** + +```go +if val, ok := app.State().GetUint16("limit"); ok { + fmt.Printf("Limit: %d\n", val) +} +``` + +### GetUint32 + +GetUint32 retrieves a `uint32` value from the State. + +```go title="Signature" +func (s *State) GetUint32(key string) (uint32, bool) +``` + +**Usage Example:** + +```go +if val, ok := app.State().GetUint32("timeout"); ok { + fmt.Printf("Timeout: %d\n", val) +} +``` + +### GetUint64 + +GetUint64 retrieves a `uint64` value from the State. + +```go title="Signature" +func (s *State) GetUint64(key string) (uint64, bool) +``` + +**Usage Example:** + +```go +if val, ok := app.State().GetUint64("maxSize"); ok { + fmt.Printf("Max Size: %d\n", val) +} +``` + +### GetUintptr + +GetUintptr retrieves a `uintptr` value from the State. + +```go title="Signature" +func (s *State) GetUintptr(key string) (uintptr, bool) +``` + +**Usage Example:** + +```go +if val, ok := app.State().GetUintptr("pointerValue"); ok { + fmt.Printf("Pointer Value: %d\n", val) +} +``` + +### GetFloat32 + +GetFloat32 retrieves a `float32` value from the State. + +```go title="Signature" +func (s *State) GetFloat32(key string) (float32, bool) +``` + +**Usage Example:** + +```go +if val, ok := app.State().GetFloat32("scalingFactor32"); ok { + fmt.Printf("Scaling Factor (float32): %f\n", val) +} +``` + +### GetComplex64 + +GetComplex64 retrieves a `complex64` value from the State. + +```go title="Signature" +func (s *State) GetComplex64(key string) (complex64, bool) +``` + +**Usage Example:** + +```go +if val, ok := app.State().GetComplex64("complexVal"); ok { + fmt.Printf("Complex Value (complex64): %v\n", val) +} +``` + +### GetComplex128 + +GetComplex128 retrieves a `complex128` value from the State. + +```go title="Signature" +func (s *State) GetComplex128(key string) (complex128, bool) +``` + +**Usage Example:** + +```go +if val, ok := app.State().GetComplex128("complexVal128"); ok { + fmt.Printf("Complex Value (complex128): %v\n", val) +} +``` + ## Generic Functions -Fiber provides generic functions to retrieve state values with type-safety and fallback options. +Fiber provides generic functions to retrieve state values with type safety and fallback options. ### GetState -GetState retrieves a value from the State and casts it to the desired type. It returns the casted value and a boolean indicating if the cast was successful. +GetState retrieves a value from the State and casts it to the desired type. It returns the cast value and a boolean indicating if the cast was successful. ```go title="Signature" func GetState[T any](s *State, key string) (T, bool) @@ -217,7 +428,7 @@ func GetState[T any](s *State, key string) (T, bool) **Usage Example:** -```go title="Signature" +```go // Retrieve an integer value safely. userCount, ok := GetState[int](app.State(), "userCount") if ok { @@ -235,7 +446,7 @@ func MustGetState[T any](s *State, key string) T **Usage Example:** -```go title="Signature" +```go // Retrieve the value or panic if it is not present. config := MustGetState[string](app.State(), "configFile") fmt.Println("Config File:", config) @@ -279,7 +490,7 @@ func main() { // Middleware: Increase counter for every request. app.Use(func(c fiber.Ctx) error { - count := fiber.GetStateWithDefault(app.State(), "requestCount", 0) + count := c.App().GetStateWithDefault(app.State(), "requestCount", 0) app.State().Set("requestCount", count+1) return c.Next() }) @@ -289,7 +500,7 @@ func main() { }) app.Get("/stats", func(c fiber.Ctx) error { - count := fiber.GetStateWithDefault(c.App().State(), "requestCount", 0) + count := c.App().GetStateWithDefault(c.App().State(), "requestCount", 0) return c.SendString(fmt.Sprintf("Total requests: %d", count)) }) @@ -297,7 +508,7 @@ func main() { } ``` -### Example: Environment-Specific Configuration +### Example: Environment–Specific Configuration This example shows how to configure different settings based on the environment. @@ -332,8 +543,8 @@ func main() { app.Get("/config", func(c fiber.Ctx) error { config := map[string]any{ "environment": environment, - "apiUrl": fiber.GetStateWithDefault(app.State(), "apiUrl", ""), - "debug": fiber.GetStateWithDefault(app.State(), "debug", false), + "apiUrl": c.App().GetStateWithDefault(app.State(), "apiUrl", ""), + "debug": c.App().GetStateWithDefault(app.State(), "debug", false), } return c.JSON(config) }) @@ -390,7 +601,7 @@ func main() { } // Save the user to the database. - rdb, ok := fiber.GetState[*redis.Client](app.State(), "redis") + rdb, ok := c.App().GetState[*redis.Client](app.State(), "redis") if !ok { return c.Status(fiber.StatusInternalServerError).SendString("Redis client not found") } @@ -408,7 +619,7 @@ func main() { app.Get("/user/:id", func(c fiber.Ctx) error { id := c.Params("id") - rdb, ok := fiber.GetState[*redis.Client](app.State(), "redis") + rdb, ok := c.App().GetState[*redis.Client](app.State(), "redis") if !ok { return c.Status(fiber.StatusInternalServerError).SendString("Redis client not found") } diff --git a/state_test.go b/state_test.go index 9cc3dfc8..365f8f77 100644 --- a/state_test.go +++ b/state_test.go @@ -7,6 +7,22 @@ import ( "github.com/stretchr/testify/require" ) +func TestState_SetAndGet_WithApp(t *testing.T) { + t.Parallel() + // Create app + app := New() + + // test setting and getting a value + app.state.Set("foo", "bar") + val, ok := app.state.Get("foo") + require.True(t, ok) + require.Equal(t, "bar", val) + + // test key not found + _, ok = app.state.Get("unknown") + require.False(t, ok) +} + func TestState_SetAndGet(t *testing.T) { t.Parallel() st := newState() @@ -320,7 +336,7 @@ func TestState_GetComplex64(t *testing.T) { t.Parallel() st := newState() - var c = complex(2, 3) + var c complex64 = complex(2, 3) st.Set("complex64", c) cRes, ok := st.GetComplex64("complex64") require.True(t, ok)