{"id":36488810,"url":"https://github.com/crunchypi/iox","last_synced_at":"2026-01-12T01:53:52.920Z","repository":{"id":248414865,"uuid":"824682705","full_name":"crunchypi/iox","owner":"crunchypi","description":"Generic extension of Go's io pkg","archived":false,"fork":false,"pushed_at":"2024-08-26T11:07:13.000Z","size":94,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-08-26T13:24:35.980Z","etag":null,"topics":["encoding-decoding","generics","go","golang","io"],"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/crunchypi.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":"2024-07-05T17:18:10.000Z","updated_at":"2024-08-26T11:06:12.000Z","dependencies_parsed_at":"2024-08-23T13:41:47.029Z","dependency_job_id":null,"html_url":"https://github.com/crunchypi/iox","commit_stats":null,"previous_names":["crunchypi/iox"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/crunchypi/iox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crunchypi%2Fiox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crunchypi%2Fiox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crunchypi%2Fiox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crunchypi%2Fiox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/crunchypi","download_url":"https://codeload.github.com/crunchypi/iox/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crunchypi%2Fiox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28331276,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T00:36:25.062Z","status":"ssl_error","status_checked_at":"2026-01-12T00:36:15.229Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["encoding-decoding","generics","go","golang","io"],"created_at":"2026-01-12T01:53:52.865Z","updated_at":"2026-01-12T01:53:52.914Z","avatar_url":"https://github.com/crunchypi.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# iox\nGeneric extension of Go's io pkg.\n\nIndex \n- [Errors](#errors)\n- [Core interfaces](#core-interfaces)\n- [Constructors](#constructors)\n- [Modifiers](#modifiers)\n\n\n\n## Errors\n\u003cdetails\u003e\n\u003csummary\u003e Expand/collapse section \u003c/summary\u003e\n\nThis package does *not* define any new errors, it inherits them from the `io` package in the standard library.\n```go\nio.EOF              // Used by e.g iox.Reader: Stop reading/consuming\nio.ErrClosedPipe    // Used by e.g iox.Writer: Stop writing/producing.\n```\n\n\u003c/details\u003e\n\n\n\n## Core interfaces\nCore interfaces are the `iox.Reader` and `iox.Writer`listed below. They mirror `io.Reader` and `io.Writer`but differ in that they work with generic values instead. An extra addition is the use of `context.Context`, since io often involves program bounds (also it gives some added flexibility).\n\n```go\ntype Reader[T any] interface {\n\tRead(context.Context) (T, error)\n}\n```\n\n```go\ntype Writer[T any] interface {\n\tWrite(context.Context, T) error\n}\n```\n\n\u003cdetails\u003e\n\u003csummary\u003e As with the io package from the standard library, iox readers and writers are combined with eachother and io.Closer. The full set of combinations can be seen by clicking here \u003c/summary\u003e\n\n```go\ntype Reader[T any] interface {\n\tRead(context.Context) (T, error)\n}\n\ntype ReadCloser[T any] interface {\n\tio.Closer\n\tReader[T]\n}\n\ntype Writer[T any] interface {\n\tWrite(context.Context, T) error\n}\n\ntype WriteCloser[T any] interface {\n\tio.Closer\n\tWriter[T]\n}\n\ntype ReadWriter[T, U any] interface {\n\tReader[T]\n\tWriter[U]\n}\n\ntype ReadWriteCloser[T, U any] interface {\n\tio.Closer\n\tReader[T]\n\tWriter[U]\n}\n```\n\u003c/details\u003e\n\n\u003cbr\u003e\n\u003cdetails\u003e\n\u003csummary\u003e  There are also \"impl\" structs which let you implement core interfaces with functions, which reduces a lot of boilerplate. These can be seen by clicking on this section \u003c/summary\u003e\n\n\u003cbr\u003e\n\nSignatures are links to the Go playground (examples).\n- [`type ReaderImpl[T any] struct`](https://go.dev/play/p/gkzrDGzLRtc)\n- [`type ReadCloserImpl[T any] struct`](https://go.dev/play/p/SXA7OWQl5ee)\n- [`type WriterImpl[T any] struct`](https://go.dev/play/p/796B8udkJKy)\n- [`type WriteCloserImpl[T any] struct`](https://go.dev/play/p/UE0Bxls3D5D)\n- [`type ReadWriterImpl[T, U any] struct`](https://go.dev/play/p/yl_e7ics0oY)\n- [`type ReadWriteCloserImpl[T, U any] struct`](https://go.dev/play/p/RvmasSrtNo_c)\n\n\u003c/details\u003e\n\n\n\n## Constructors\n\nAll links go to examples on the Go playground.\n\n- [`func NewReaderFrom[T any](vs ...T) Reader[T]`](https://go.dev/play/p/bP73PU1mQvf)\n- [`func NewReaderFromBytes[T any](r io.Reader) func(f decoderFn) Reader[T]`](https://go.dev/play/p/ltcwrgk41Gw)\n- [`func NewReaderFromValues[T any](r Reader[T]) func(f encoderFn) io.Reader`](https://go.dev/play/p/e9Sp5od3iE6)\n- [`func NewWriterFromValues[T any](w io.Writer) func(f encoderFn) Writer[T]`](https://go.dev/play/p/5arKiC4ZxRt)\n- [`func NewWriterFromBytes[T any](w Writer[T]) func(f decoderFn) io.Writer`](https://go.dev/play/p/yhaEWVIMoxw)\n- [`func NewReadWriterFrom[T any](vs ...T) ReadWriter[T, T]`](https://go.dev/play/p/tusGzivubiI)\n\n\u003cdetails\u003e\n\u003csummary\u003e Alternatively, you may see signatures and docs by clicking here\u003c/summary\u003e\n\n\n```go\n// NewReaderFrom returns a Reader which yields values from the given vals.\nfunc NewReaderFrom[T any](vs ...T) Reader[T]\n```\n\n```go\n// NewReaderFromBytes creates a new T reader from an io.Reader and Decoder.\n// It simply reads bytes from 'r', decodes them, and passes them along to the\n// caller. As such, the decoder must match the encoder used to create the bytes.\n// If 'r' is nil, an empty Reader is returned; if 'f' is nil, the decoder is set\n// to json.NewDecoder.\nfunc NewReaderFromBytes[T any](r io.Reader) func(f decoderFn) Reader[T]\n```\n\n```go\n// NewReaderFromValues creates an io.Reader from a Reader and Encoder.\n// It simply reads values from 'r', encodes them, and passes them along to the\n// caller. As such, when decoding values from the returned io.Reader one should\n// use a decoder which matches the encoder passed here. If 'r' is nil, an\n// empty (not nil) io.Reader is returned; if 'f' is nil, the encoder is set to\n// json.NewEncoder. \nfunc NewReaderFromValues[T any](r Reader[T]) func(f encoderFn) io.Reader\n```\n\n```go\n// NewWriterFromValues returns a Writer which accepts values, encodes them\n// using the given encoder, and then writes them to 'w'. If 'w' is nil, an empty\n// Writer is returned; if 'f' is nil, the encoder is set to json.NewEncoder.\nfunc NewWriterFromValues[T any](w io.Writer) func(f encoderFn) Writer[T]\n```\n\n```go\n// NewWriterFromBytes returns an io.Writer which accepts bytes, decodes them\n// using the given decoder, and then writes them to 'w'. If 'w' is nil, an emtpy\n// io.Writer is returned; if 'f' is nil, the decoder is set to json.NewDecoder.\nfunc NewWriterFromBytes[T any](w Writer[T]) func(f decoderFn) io.Writer \n```\n\n```go\n// NewReadWriterFrom returns a ReadWriter[T] which writes into- and read from\n// an internal buffer. The buffer is initially populated with the given values.\n// The buffer acts like a stack, and a read while the buf is empty returns io.EOF.\nfunc NewReadWriterFrom[T any](vs ...T) ReadWriter[T, T]\n```\n\u003c/details\u003e\n\n\n\n## Modifiers\nAll links go to examples on the Go playground.\n\nBatching.\n- [`func NewReaderWithBatching[T any](r Reader[T], size int) Reader[[]T]`](\n\thttps://go.dev/play/p/Mn3Cipq8-Gy\n)\n- [`func NewReaderWithUnbatching[T any](r Reader[[]T]) Reader[T]`](\n\thttps://go.dev/play/p/zaLBILUnkgE\n)\n- [`func NewWriterWithBatching[T any](w Writer[[]T], size int) Writer[T]`](\n\thttps://go.dev/play/p/sbOaajf3Jt8\n)\n- [`func NewWriterWithUnbatching[T any](w Writer[T]) Writer[[]T]`](\n\thttps://go.dev/play/p/E-qP0CE8wV3\n)\n\nFiltering \u0026 mapping.\n* [`func NewReaderWithFilterFn[T any](r Reader[T]) func(f func(v T) bool) Reader[T]`](\n\thttps://go.dev/play/p/vYCJChGUKF_Y\n)\n* [`func NewReaderWithMapperFn[T, U any](r Reader[T]) func(f func(T) U) Reader[U]`](\n\thttps://go.dev/play/p/CaB0N1N5nur\n)\n* [`func NewWriterWithFilterFn[T any](w Writer[T]) func(f func(T) bool) Writer[T]`](\n\thttps://go.dev/play/p/BgKAgGVvJ7b\n)\n* [`func NewWriterWithMapperFn[T, U any](w Writer[U]) func(f func(T) U) Writer[T]`](\n\thttps://go.dev/play/p/V3OvYkJS-mC\n)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrunchypi%2Fiox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcrunchypi%2Fiox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrunchypi%2Fiox/lists"}