{"id":20608756,"url":"https://github.com/andeya/gust","last_synced_at":"2025-12-29T18:25:13.142Z","repository":{"id":40512043,"uuid":"482014760","full_name":"andeya/gust","owner":"andeya","description":"A Rust-inspired declarative-programming and generic-type module for Golang that helps avoid bugs and improve development efficiency.","archived":false,"fork":false,"pushed_at":"2023-05-15T08:19:43.000Z","size":476,"stargazers_count":114,"open_issues_count":2,"forks_count":8,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-03-28T15:51:48.454Z","etag":null,"topics":["declarative","ergonomic","error-handling","go","go-generics","iterator","option","result"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andeya.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2022-04-15T16:13:12.000Z","updated_at":"2025-03-10T03:27:46.000Z","dependencies_parsed_at":"2023-07-13T05:02:18.068Z","dependency_job_id":null,"html_url":"https://github.com/andeya/gust","commit_stats":null,"previous_names":["henrylee2cn/gust"],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andeya%2Fgust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andeya%2Fgust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andeya%2Fgust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andeya%2Fgust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andeya","download_url":"https://codeload.github.com/andeya/gust/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249004736,"owners_count":21196934,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["declarative","ergonomic","error-handling","go","go-generics","iterator","option","result"],"created_at":"2024-11-16T10:11:46.883Z","updated_at":"2025-12-25T05:16:12.742Z","avatar_url":"https://github.com/andeya.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# gust 🌬️\n\n[![tag](https://img.shields.io/github/tag/andeya/gust.svg)](https://github.com/andeya/gust/releases)\n![Go Version](https://img.shields.io/badge/Go-%3E%3D%201.19-%23007d9c)\n[![GoDoc](https://godoc.org/github.com/andeya/gust?status.svg)](https://pkg.go.dev/github.com/andeya/gust)\n![Build Status](https://github.com/andeya/gust/actions/workflows/go-ci.yml/badge.svg)\n[![Go report](https://goreportcard.com/badge/github.com/andeya/gust)](https://goreportcard.com/report/github.com/andeya/gust)\n[![Coverage](https://img.shields.io/codecov/c/github/andeya/gust)](https://codecov.io/gh/andeya/gust)\n[![License](https://img.shields.io/github/license/andeya/gust)](./LICENSE)\n\n**Bring Rust's elegance to Go** - A powerful library that makes error handling, optional values, and iteration as beautiful and safe as in Rust.\n\n\u003e 🎯 **Zero dependencies** • 🚀 **Production ready** • 📚 **Well documented** • ✨ **Type-safe**\n\n**Languages:** [English](./README.md) | [中文](./README_ZH.md)\n\n## ✨ Why gust?\n\nTired of writing `if err != nil` everywhere? Frustrated with nil pointer panics? Want Rust-like iterator chains in Go?\n\n**gust** brings Rust's best patterns to Go, making your code:\n- 🛡️ **Safer** - No more nil pointer panics\n- 🎯 **Cleaner** - Chain operations elegantly\n- 🚀 **More Expressive** - Write what you mean, not boilerplate\n\n### From Imperative to Declarative\n\ngust helps you shift from **imperative** (focusing on *how*) to **declarative** (focusing on *what*) programming:\n\n![Declarative vs Imperative](./doc/declarative_vs_imperative.jpg)\n\nWith gust, you describe **what** you want to achieve, not **how** to achieve it step-by-step. This makes your code more readable, maintainable, and less error-prone.\n\n### Before gust (Traditional Go)\n```go\nfunc fetchUserData(userID int) (string, error) {\n    // Step 1: Fetch from database\n    user, err := db.GetUser(userID)\n    if err != nil {\n        return \"\", fmt.Errorf(\"db error: %w\", err)\n    }\n    \n    // Step 2: Validate user\n    if user == nil {\n        return \"\", fmt.Errorf(\"user not found\")\n    }\n    if user.Email == \"\" {\n        return \"\", fmt.Errorf(\"invalid user: no email\")\n    }\n    \n    // Step 3: Fetch profile\n    profile, err := api.GetProfile(user.Email)\n    if err != nil {\n        return \"\", fmt.Errorf(\"api error: %w\", err)\n    }\n    \n    // Step 4: Format result\n    result := fmt.Sprintf(\"%s: %s\", user.Name, profile.Bio)\n    return result, nil\n}\n```\n\n### After gust (Elegant \u0026 Safe)\n```go\nimport \"github.com/andeya/gust\"\nimport \"github.com/andeya/gust/ret\"\n\nfunc fetchUserData(userID int) gust.Result[string] {\n    return ret.AndThen(gust.Ret(getUser(userID)), func(user *User) gust.Result[string] {\n        if user == nil || user.Email == \"\" {\n            return gust.Err[string](\"invalid user\")\n        }\n        return ret.Map(gust.Ret(getProfile(user.Email)), func(profile *Profile) string {\n            return fmt.Sprintf(\"%s: %s\", user.Name, profile.Bio)\n        })\n    })\n}\n\n// See ExampleResult_fetchUserData in examples/ for a complete runnable example\n```\n\n**What changed?**\n- ✅ **No error boilerplate** - Errors flow naturally through the chain\n- ✅ **No nested if-else** - Linear flow, easy to read\n- ✅ **Automatic propagation** - Errors stop the chain automatically\n- ✅ **Composable** - Each step is independent and testable\n- ✅ **Type-safe** - Compiler enforces correct error handling\n\n## 🚀 Quick Start\n\n```bash\ngo get github.com/andeya/gust\n```\n\n## 📚 Core Features\n\n### 1. Result\u003cT\u003e - Elegant Error Handling\n\nReplace `(T, error)` with chainable `Result[T]`:\n\n```go\nimport \"github.com/andeya/gust\"\nimport \"github.com/andeya/gust/ret\"\n\n// Chain operations that can fail\nresult := gust.Ok(10).\n    Map(func(x int) int { return x * 2 }).\n    AndThen(func(x int) gust.Result[int] {\n        if x \u003e 15 {\n            return gust.Err[int](\"too large\")\n        }\n        return gust.Ok(x + 5)\n    }).\n    OrElse(func(err error) gust.Result[int] {\n        fmt.Println(\"Error handled:\", err)\n        return gust.Ok(0) // Fallback\n    })\n\nfmt.Println(\"Final value:\", result.Unwrap())\n// Output: Error handled: too large\n// Final value: 0\n```\n\n**Key Benefits:**\n- ✅ No more `if err != nil` boilerplate\n- ✅ Automatic error propagation\n- ✅ Chain multiple operations elegantly\n- ✅ Type-safe error handling\n\n### 2. Option\u003cT\u003e - No More Nil Panics\n\nReplace `*T` and `(T, bool)` with safe `Option[T]`:\n\n```go\n// Safe division without nil checks\ndivide := func(a, b float64) gust.Option[float64] {\n    if b == 0 {\n        return gust.None[float64]()\n    }\n    return gust.Some(a / b)\n}\n\nresult := divide(10, 2).\n    Map(func(x float64) float64 { return x * 2 }).\n    UnwrapOr(0)\n\nfmt.Println(result) // 10\n```\n\n**Key Benefits:**\n- ✅ Eliminates nil pointer panics\n- ✅ Explicit optional values\n- ✅ Chain operations safely\n- ✅ Compiler-enforced safety\n\n### 3. Iterator - Rust-like Iteration in Go\n\nFull Rust Iterator trait implementation with method chaining:\n\n```go\nimport \"github.com/andeya/gust/iter\"\n\nnumbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}\n\nsum := iter.FromSlice(numbers).\n    Filter(func(x int) bool { return x%2 == 0 }).\n    Map(func(x int) int { return x * x }).\n    Take(3).\n    Fold(0, func(acc int, x int) int {\n        return acc + x\n    })\n\nfmt.Println(sum) // 56 (4 + 16 + 36)\n```\n\n**Available Methods:**\n- **Adapters**: `Map`, `Filter`, `Chain`, `Zip`, `Enumerate`, `Skip`, `Take`, `StepBy`, `FlatMap`, `Flatten`\n- **Consumers**: `Fold`, `Reduce`, `Collect`, `Count`, `All`, `Any`, `Find`, `Sum`, `Product`, `Partition`\n- **Advanced**: `Scan`, `Intersperse`, `Peekable`, `ArrayChunks`, `FindMap`, `MapWhile`\n- **Double-Ended**: `NextBack`, `Rfold`, `TryRfold`, `Rfind`\n- And 60+ more methods from Rust's Iterator trait!\n\n**Note:** For type-changing operations (e.g., `Map` from `string` to `int`), use the function-style API:\n```go\niter.Map(iter.FromSlice(strings), func(s string) int { return len(s) })\n```\n\nFor same-type operations, you can use method chaining:\n```go\niter.FromSlice(numbers).Filter(func(x int) bool { return x \u003e 0 }).Map(func(x int) int { return x * 2 })\n```\n\n**Key Benefits:**\n- ✅ Rust-like method chaining\n- ✅ Lazy evaluation\n- ✅ Type-safe transformations\n- ✅ Zero-copy where possible\n\n### 4. Double-Ended Iterator\n\nIterate from both ends:\n\n```go\nimport \"github.com/andeya/gust/iter\"\n\nnumbers := []int{1, 2, 3, 4, 5}\ndeIter := iter.FromSlice(numbers).MustToDoubleEnded()\n\n// Iterate from front\nif val := deIter.Next(); val.IsSome() {\n    fmt.Println(\"Front:\", val.Unwrap()) // Front: 1\n}\n\n// Iterate from back\nif val := deIter.NextBack(); val.IsSome() {\n    fmt.Println(\"Back:\", val.Unwrap()) // Back: 5\n}\n```\n\n## 📖 More Examples\n\n### Parse and Filter with Error Handling\n\n```go\nimport \"github.com/andeya/gust\"\nimport \"github.com/andeya/gust/iter\"\nimport \"strconv\"\n\n// Parse strings to integers, automatically filtering out errors\nnumbers := []string{\"1\", \"2\", \"three\", \"4\", \"five\"}\n\nresults := iter.FilterMap(\n    iter.Map(iter.FromSlice(numbers), func(s string) gust.Result[int] {\n        return gust.Ret(strconv.Atoi(s))\n    }),\n    gust.Result[int].Ok).\n    Collect()\n\nfmt.Println(\"Parsed numbers:\", results)\n// Output: Parsed numbers: [1 2 4]\n```\n\n### Real-World Data Pipeline\n\n```go\n// Process user input: parse, validate, transform, limit\ninput := []string{\"10\", \"20\", \"invalid\", \"30\", \"0\", \"40\"}\n\nresults := iter.FilterMap(\n    iter.Map(iter.FromSlice(input), func(s string) gust.Result[int] {\n        return gust.Ret(strconv.Atoi(s))\n    }),\n    gust.Result[int].Ok).\n    Filter(func(x int) bool { return x \u003e 0 }).\n    Map(func(x int) int { return x * 2 }).\n    Take(3).\n    Collect()\n\nfmt.Println(results) // [20 40 60]\n```\n\n### Option Chain Operations\n\n```go\n// Chain operations on optional values with filtering\nresult := gust.Some(5).\n    Map(func(x int) int { return x * 2 }).\n    Filter(func(x int) bool { return x \u003e 8 }).\n    XMap(func(x int) any {\n        return fmt.Sprintf(\"Value: %d\", x)\n    }).\n    UnwrapOr(\"No value\")\n\nfmt.Println(result) // \"Value: 10\"\n```\n\n### Partition Data\n\n```go\n// Split numbers into evens and odds\nnumbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}\n\nevens, odds := iter.FromSlice(numbers).\n    Partition(func(x int) bool { return x%2 == 0 })\n\nfmt.Println(\"Evens:\", evens) // [2 4 6 8 10]\nfmt.Println(\"Odds:\", odds)   // [1 3 5 7 9]\n```\n\n## 🎯 Use Cases\n\n- **Error Handling**: Replace `(T, error)` with `Result[T]` for cleaner, chainable error handling\n- **Optional Values**: Use `Option[T]` instead of `*T` for nil safety and explicit optional semantics\n- **Data Processing**: Chain iterator operations for elegant, lazy-evaluated data transformations\n- **API Responses**: Handle optional/error cases explicitly without nil checks\n- **Configuration**: Use `Option` for optional config fields with type safety\n- **Data Validation**: Combine `Result` and `Option` for robust input validation pipelines\n\n## 📦 Additional Packages\n\n- **`gust/dict`** - Generic map utilities (Filter, Map, Keys, Values, etc.)\n- **`gust/vec`** - Generic slice utilities  \n- **`gust/valconv`** - Type-safe value conversion\n- **`gust/digit`** - Number conversion utilities\n- **`gust/sync`** - Generic sync primitives (Mutex, RWMutex, etc.)\n\n### Dict Utilities Example\n\n```go\nimport \"github.com/andeya/gust/dict\"\n\nm := map[string]int{\"a\": 1, \"b\": 2, \"c\": 3}\n\n// Get with Option\nvalue := dict.Get(m, \"b\")\nfmt.Println(value.UnwrapOr(0)) // 2\n\n// Filter map\nfiltered := dict.Filter(m, func(k string, v int) bool {\n    return v \u003e 1\n})\nfmt.Println(filtered) // map[b:2 c:3]\n\n// Map values\nmapped := dict.MapValue(m, func(k string, v int) int {\n    return v * 2\n})\nfmt.Println(mapped) // map[a:2 b:4 c:6]\n```\n\n### Vec Utilities Example\n\n```go\nimport \"github.com/andeya/gust/vec\"\n\n// Map slice elements\nnumbers := []int{1, 2, 3, 4, 5}\ndoubled := vec.MapAlone(numbers, func(x int) int {\n    return x * 2\n})\nfmt.Println(doubled) // [2 4 6 8 10]\n\n// Convert []any to specific type\nanySlice := []any{1, 2, 3, 4, 5}\nintSlice := vec.MapAlone(anySlice, func(v any) int {\n    return v.(int)\n})\nfmt.Println(intSlice) // [1 2 3 4 5]\n```\n\n## 🔗 Resources\n\n- 📖 [Full Documentation](https://pkg.go.dev/github.com/andeya/gust) - Complete API reference\n- 💡 [Examples](./examples/) - Comprehensive examples organized by feature\n- 🌐 [中文文档](./README_ZH.md) - Chinese documentation\n- 🐛 [Issue Tracker](https://github.com/andeya/gust/issues) - Report bugs or request features\n- 💬 [Discussions](https://github.com/andeya/gust/discussions) - Ask questions and share ideas\n\n## 📋 Go Version\n\nRequires **Go 1.19+** (for generics support)\n\n## 🤝 Contributing\n\nContributions are welcome! Whether it's:\n- 🐛 Reporting bugs\n- 💡 Suggesting new features\n- 📝 Improving documentation\n- 🔧 Submitting pull requests\n\nEvery contribution makes gust better! Please feel free to submit a Pull Request or open an issue.\n\n## 📄 License\n\nThis project is licensed under the MIT License.\n\n---\n\n**Made with ❤️ for the Go community**\n\n*Inspired by Rust's `Result`, `Option`, and `Iterator` traits*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandeya%2Fgust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandeya%2Fgust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandeya%2Fgust/lists"}