{"id":17169388,"url":"https://github.com/johnmurray/typed","last_synced_at":"2025-03-24T19:18:20.832Z","repository":{"id":137211293,"uuid":"441196820","full_name":"JohnMurray/typed","owner":"JohnMurray","description":"Pragmatic type-wrapping for Go 1.18+","archived":false,"fork":false,"pushed_at":"2022-01-02T17:21:01.000Z","size":33,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-29T23:41:41.206Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/JohnMurray.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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-12-23T13:57:42.000Z","updated_at":"2022-01-02T17:21:04.000Z","dependencies_parsed_at":null,"dependency_job_id":"48364ee1-1c8e-4b78-be68-c058cb04ea51","html_url":"https://github.com/JohnMurray/typed","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohnMurray%2Ftyped","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohnMurray%2Ftyped/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohnMurray%2Ftyped/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohnMurray%2Ftyped/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JohnMurray","download_url":"https://codeload.github.com/JohnMurray/typed/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245334909,"owners_count":20598389,"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":[],"created_at":"2024-10-14T23:26:03.904Z","updated_at":"2025-03-24T19:18:20.812Z","avatar_url":"https://github.com/JohnMurray.png","language":"Go","readme":"# typed\n[![Go](https://github.com/JohnMurray/typed/actions/workflows/go.yml/badge.svg?branch=main)](https://github.com/JohnMurray/typed/actions/workflows/go.yml)\n [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n ![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/johnmurray/typed)\n\nTyped is a simple and pragmatic set of type wrappers for common use-cases with Go 1.18+. This library\naims to be simple and __usable in production__ environments.\n\nThe Go team decided [_not to update libraries_][no_change] in 1.18 alongside the release of generics.\nI strongly agree with this move, and so this library aims to provide wrappers for common operations\nand types as both an experiment in typing in Go 1.18+ and also a transitionary package as the standard\nlibrary evolves over future releases.\n\n## Installation\n\n```shell\ngo get -d github.com/johnmurray/typed@main\n```\n\n__Note__: This _requires_ Go 1.18+ to use.\n\n\n## Examples and Docs\n\npkg.go.dev doesn't currently support documentation generation for generics. So please refer\nto the below examples for reference. Also feel free to read the source if that's your jam.\n\n  + [`Queue[T]`](#queuet)\n  + [`Stack[T]`](#stackt)\n  + [`Set[T]`](#sett)\n  + Test Utilities\n    + [`Must[T]`](#mustt)\n    + [`MustT[T]`](#musttt)\n    + [`MustB[T]`](#mustbt)\n\nFor free-standing functional methods, see the [functional][func] sub-package.\n\n### `Queue[T]`\n\nA `chan T` backed queue implementation.\n\n```go\n// Allocate a queue with a fixed capacity\nq := NewQueue[int](100)\n\n// Defer close the queue (closes for writing, but not reading)\ndefer q.Close()\n\n// Fill up the queue using synchronous pushes. This is fine\n// since we have he capacity and will be immediate.\nfor i := 0; i \u003c 100; i++ {\n  q.Pushes(i)\n}\n\ngo func() {\n  // Because we're at capacity, this will block until the\n  // queue is read from and some capacity is freed up\n  q.Push(101)\n}()\n\n// We can attempt to push async as well. This will return\n// 'false' if the queue is full, but returns immediately.\nif q.TryPush(102) {\n  panic(\"queue should be full and return false\")\n}\n\n// Current length should equal the capacity\nfmt.Printf(\"%d\\n\", q.Length())\n\n// Pop all of our items off of the queue (including the one\n// pending additional capacity)\nfor i := 0; i \u003c 101; i++ {\n  fmt.Printf(\"%d\\n\", q.Pop())\n}\n\ngo func() {\n  // Popping is also synchronous so this will block until more\n  // data is pushed onto the queue\n  q.Pop()\n}()\n\n// We can attempt to pull async. This return the value and a\n// true/false value indicating success. If the queue is empty\n// then the empty-value for the type + false is returned.\nif val, ok := q.TryPop(); ok {\n  panic(\"queue should be empty\")\n}\n\n// We could also use TryPop to loop over only the current items\n// in the queue\nval, ok := q.TryPop()\nfor ok {\n  // use value ...\n  // then consume the next one\n  val, ok = q.TryPop()\n}\n```\n\n### `Stack[T]`\n\nA slice-backed Stack implementation.\n\n```go\n// Allocate a stack just as you would a slice\ns := make(Stack[string], 0, 100)\n\n// Push should always succeed. Since the Stack is range-backed, this will use\n// and append and should take care of growing the stack\ns.Push(\"one\")\ns.Push(\"two\")\n\n// Popping should return the value or, if the Stack is empty, a non-nil error\n// response\nvalue, err := s.Pop()\n```\n\n### `Set[T]`\n\nA wrapper around `map[T]struct{}` for set operations.\n\n```go\n// allocate your set in the same way you would a map\ns := make(Set[string])\n\n// OR you can allocate and assign initial values\ns = MakeSet(\"one\", \"two\", \"three\")\n\n// check the length with len()\nlen(s)\n\nif !s.Has(\"four\") {\n  s.Add(\"four\")\n}\n\n// Adding duplicates is fine\nlenBefore := len(s)\ns.Add(\"four\")\nif lenBefore != len(s) {\n  panic(\"should account for duplicates\")\n}\n\n// Iterate with ForEach, or with a for-loop\ns.ForEach(func(value string) { fmt.Println(value) })\nfor value, _ := range s {\n  fmt.Println(value)\n}\n\n// Perform common set operations\nMakeSet(1, 2, 3).Intersection(MakeSet(2, 3, 4)) // == MakeSet(2, 3)\nMakeSet(1, 2, 3).Union(MakeSet(2, 3, 4))        // == MakeSet(1, 2, 3, 4)\nMakeSet(1, 2, 3).Subtract(MakeSet(2, 3, 4))     // == MakeSet(1)\n```\n\n### Test Utilities\n\n#### `Must[T]`\n\nAssert that a function returning a `(value, error)` tuple returns a `nil`\nerror. If a non-`nil` error is returned, the function will panic.\n\n```go\nfunc MaybeValue() (int, error) { /* ... */ }\n\nfunc TestMaybeValue(t *testing.T) {\n  // get the first return value\n  value := Must(MaybeValue())\n}\n```\n\n#### `MustT[T]`\n\nAssert that a function returning a `(value, error)` tuple returns a `nil`\nerror. If a non-`nil` error is returned, the function will call `t.Fatalf`.\n\n```go\nfunc MaybeValue() (int, error) { /* ... */ }\n\nfunc TestMaybeValue(t *testing.T) {\n  // get the first return value\n  value := Must(MaybeValue())(t)\n}\n```\n\nThis may be called with `testing.T` or `testing.B`. The `testing.T` parameter\ncomes in a second parameter list to aid with better type deduction.\n\n#### `MustB[T]`\n\nAlias for `MustT[T]`.\n\n\n  [no_change]: https://github.com/golang/go/issues/48918\n  [func]: https://github.com/JohnMurray/typed/tree/main/functional","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnmurray%2Ftyped","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohnmurray%2Ftyped","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnmurray%2Ftyped/lists"}