add cde
This commit is contained in:
parent
461b545fd9
commit
4d19b8a8df
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
// 使用 IntelliSense 了解相关属性。
|
||||
// 悬停以查看现有属性的描述。
|
||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": []
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
package gostream
|
||||
|
||||
import "errors"
|
||||
|
||||
type StreamOption struct {
|
||||
WaterMark int // buffer len
|
||||
}
|
||||
|
||||
type IReadAble[T any] interface {
|
||||
StartRead() chan T
|
||||
}
|
||||
|
||||
type IReadStream[T any] interface {
|
||||
OnData(func(T)) error
|
||||
Read() (T, error)
|
||||
Pipe(w IWriteStream[T]) error
|
||||
}
|
||||
|
||||
type IWriteAble[T any] interface {
|
||||
StartWrite() chan T
|
||||
}
|
||||
|
||||
type IWriteStream[T any] interface {
|
||||
Write(T)
|
||||
}
|
||||
type WriteStream[T any] struct {
|
||||
IWriteAble[T]
|
||||
IWriteStream[T]
|
||||
writeChan chan T
|
||||
// isSync bool
|
||||
}
|
||||
|
||||
func (w *WriteStream[T]) Write(t T) {
|
||||
if w.writeChan == nil {
|
||||
w.writeChan = w.StartWrite()
|
||||
}
|
||||
w.writeChan <- t
|
||||
}
|
||||
|
||||
type ReadStream[T any] struct {
|
||||
IReadAble[T]
|
||||
IReadStream[T]
|
||||
readChan chan T
|
||||
isSync bool
|
||||
}
|
||||
|
||||
// func (r *ReadStream[T]) StartRead() <-chan T {
|
||||
// return nil
|
||||
// }
|
||||
func (r *ReadStream[T]) OnData(cb func(T)) error {
|
||||
if r.readChan != nil {
|
||||
return errors.New("already has reader")
|
||||
}
|
||||
r.readChan = r.StartRead()
|
||||
|
||||
go func() {
|
||||
for t := range r.readChan {
|
||||
cb(t)
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ReadStream[T]) Read() (T, error) {
|
||||
if r.readChan != nil && !r.isSync {
|
||||
return *new(T), errors.New("already has reader")
|
||||
}
|
||||
if r.readChan == nil {
|
||||
r.readChan = r.StartRead()
|
||||
r.isSync = true
|
||||
}
|
||||
|
||||
return <-r.readChan, nil
|
||||
}
|
||||
|
||||
func (r *ReadStream[T]) Pipe(w IWriteStream[T]) error {
|
||||
if r.readChan != nil {
|
||||
return errors.New("already has reader")
|
||||
}
|
||||
r.readChan = r.StartRead()
|
||||
go func() {
|
||||
for t := range r.readChan {
|
||||
w.Write(t)
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
type ITransformer[T any, K any] interface {
|
||||
Transform(t T) K
|
||||
}
|
||||
|
||||
type TransformStream[T any, K any] struct {
|
||||
Options StreamOption
|
||||
IWriteAble[T]
|
||||
WriteStream[T]
|
||||
IReadAble[K]
|
||||
ReadStream[K]
|
||||
ITransformer[T, K]
|
||||
writer chan T
|
||||
reader chan K
|
||||
}
|
||||
|
||||
func (tr *TransformStream[T, K]) StartRead() chan K {
|
||||
if tr.reader != nil {
|
||||
return tr.reader
|
||||
}
|
||||
return make(chan K, tr.Options.WaterMark)
|
||||
}
|
||||
|
||||
func (tr *TransformStream[T, K]) StartWrite() chan T {
|
||||
if tr.writer != nil {
|
||||
return tr.writer
|
||||
}
|
||||
return make(chan T, tr.Options.WaterMark)
|
||||
}
|
||||
|
||||
func (tr *TransformStream[T, K]) OnData(cb func(K)) error {
|
||||
err := tr.ReadStream.OnData(cb)
|
||||
if err == nil {
|
||||
if tr.writer == nil {
|
||||
tr.writer = tr.StartWrite()
|
||||
}
|
||||
go func() {
|
||||
for k := range tr.writer {
|
||||
transfered := tr.ITransformer.Transform(k)
|
||||
tr.reader <- transfered
|
||||
}
|
||||
}()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func NewTransform[T any, K any](t ITransformer[T, K], options StreamOption) *TransformStream[T, K] {
|
||||
ret := &TransformStream[T, K]{
|
||||
Options: options,
|
||||
ITransformer: t,
|
||||
ReadStream: ReadStream[K]{},
|
||||
WriteStream: WriteStream[T]{},
|
||||
}
|
||||
ret.ReadStream.IReadAble = ret
|
||||
ret.WriteStream.IWriteAble = ret
|
||||
return ret
|
||||
}
|
||||
|
||||
func NewReadStream[T any](reader IReadAble[T]) *ReadStream[T] {
|
||||
ret := &ReadStream[T]{
|
||||
IReadAble: reader,
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func NewWriteStream[T any](writer IWriteAble[T]) *WriteStream[T] {
|
||||
ret := &WriteStream[T]{
|
||||
IWriteAble: writer,
|
||||
}
|
||||
return ret
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.pyer.club/kingecg/gostream"
|
||||
)
|
||||
|
||||
type TReadAble[T any] struct {
|
||||
gostream.ReadStream[T]
|
||||
sended int
|
||||
E []T
|
||||
}
|
||||
|
||||
func (tr *TReadAble[T]) StartRead() chan T {
|
||||
// var d T
|
||||
// if tr.sended < len(tr.E) {
|
||||
// d = tr.E[tr.sended]
|
||||
// tr.sended++
|
||||
// return &d
|
||||
// }
|
||||
// return nil
|
||||
|
||||
ch := make(chan T)
|
||||
go func() {
|
||||
for i := 0; i < len(tr.E); i++ {
|
||||
ch <- tr.E[i]
|
||||
}
|
||||
close(ch)
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
func main() {
|
||||
|
||||
x := &TReadAble[int]{
|
||||
gostream.ReadStream[int]{},
|
||||
0,
|
||||
[]int{1, 2, 3, 4, 5},
|
||||
}
|
||||
x.ReadStream.IReadAble = x
|
||||
// x.OnData(func(d int) {
|
||||
// fmt.Println(d)
|
||||
// })
|
||||
fmt.Println(x.Read())
|
||||
fmt.Println(x.Read())
|
||||
fmt.Println(x.Read())
|
||||
fmt.Println(x.Read())
|
||||
|
||||
// for t := tr.DoRead(); t != nil; t = tr.DoRead() {
|
||||
// fmt.Println(*t)
|
||||
// }
|
||||
// tr.OnData(func(d int) {
|
||||
// fmt.Println("tr.OnData", d)
|
||||
// })
|
||||
select {}
|
||||
|
||||
}
|
Loading…
Reference in New Issue